Избежать рекурсии при синхронном чтении / записи порта?


108

Все операции с портами в Rebol 3 асинхронны. Единственный способ синхронного общения, который я могу найти, - это позвонить wait.

Но проблема с вызовом wait в этом случае заключается в том, что он будет проверять события для всех открытых портов (даже если они не находятся в блоке портов, переданном для ожидания). Затем они вызывают свои отвечающие обработчики событий, но чтение / запись могут выполняться в одном из этих обработчиков событий. Это может привести к рекурсивным вызовам «ожидания».

Как мне обойти это?


8
На самом деле, я не думаю, что есть решение этой проблемы в текущей реализации R3, поэтому я пошел дальше, чтобы добавить уточнение «/ only» для «wait», с помощью которого он будет ждать только на портах, предоставленных для «ожидания» , и таким образом избежать рекурсивных вызовов. См. Мой запрос на
перенос по

1
Из любопытства, зачем вам синхронность?
toadzky 09

1
Есть много ситуаций, когда кодирование с синхронным портом намного проще: предположим, вы хотите отправить электронное письмо, щелкнув кнопку, и сообщить, удастся ли оно или нет. Гораздо проще дождаться его завершения, прежде чем делать что-либо еще.
Шисинь Цзэн,

1
вам обязательно нужно использовать Rebol?
Ривенфолл

1
Да. На самом деле это скорее вопрос о Rebol 3, чем о синхронном общении в целом.
Шисинь Цзэн

Ответы:


1

Почему бы вам не создать своего рода функцию «Буфера», чтобы получать все сообщения от синхронных записей и обрабатывать их как FIFO (first-in, first-out)?

Таким образом, вы можете сохранить характеристики Assync ваших портов и обработать их в режиме синхронизации.


0

в случаях, когда есть только асинхронные события, и нам нужен синхронный ответ, запустите таймер или спящий режим для тайм-аута, если обработчик или требуемая цель достигнута, тогда скажите true, иначе false и убедитесь, что событие отменено / сброшено для то же самое, если критично.


0

Я думаю, что есть 2 проблемы с дизайном (возможно, присущие имеющимся инструментам / решениям).

  1. Waitделает слишком много - it will check events for all open ports. В здоровой среде ожидание должно реализовываться только там, где это необходимо: на устройство, на порт, на сокет ... Создание ненужных взаимозависимостей между общими ресурсами не может закончиться хорошо, особенно зная, что общие ресурсы (даже без взаимозависимостей) может создать много проблем.

  2. Обработчики событий могут делать слишком много. Обработчик событий должен быть как можно короче и обрабатывать только событие. Если он делает больше, значит, обработчик делает слишком много, особенно если задействует другие общие ресурсы. Во многих ситуациях обработчик просто сохраняет данные, которые в противном случае будут потеряны; а асинхронная работа будет делать более сложные вещи.


-1

Вы можете просто использовать замок. Cummunication1 может установить некоторое состояние глобальной блокировки, то есть с помощью переменной (убедитесь, что это потокобезопасно). locked = true. Тогда Communication2 может подождать, пока он не разблокируется.

loop do
    sleep 10ms
    break if not locked
end
locked = true
handle_communication()

1
На самом деле это скорее вопрос о Rebol 3, чем о синхронном общении в целом.
Шисинь Цзэн
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.