Уникаючи рекурсії під час читання / запису порту синхронно?


108

Усі портові операції в Rebol 3 є асинхронними. Єдиний спосіб, коли я можу знайти синхронний зв’язок - це дзвінки wait.

Але проблема з викликом очікування в цьому випадку полягає в тому, що він перевірятиме події для всіх відкритих портів (навіть якщо вони не перебувають у блоці портів, переданому на очікування). Потім вони зателефонують на відповідні обробники подій, але читання / запис можна зробити в одному з цих обробників подій. Це може призвести до рекурсивних викликів "чекати".

Як мені це обійти?


8
Насправді, я не думаю, що для цього є рішення у поточній реалізації R3, тому я продовжував додавати "/ only" уточнення до "зачекати", з яким він буде чекати лише на портах, передбачених для "очікування" і, таким чином, уникати рекурсивних дзвінків. Дивіться мого запиту на потяг за адресою: github.com/rebol/rebol/pull/177
Shixin Zeng

1
З цікавості, навіщо вам це синхронічно?
toadzky

1
Існує багато ситуацій, коли кодування за допомогою синхронного порту набагато простіше: припустимо, ви хочете надіслати електронний лист одним натисканням кнопки та повідомити, чи вдалося це чи не вдасться. Набагато простіше дочекатися її закінчення, перш ніж робити щось інше.
Шиксин Зенг

1
ви абсолютно повинні використовувати Rebol?
Rivenfall

1
Так. Це насправді більше питання про Rebol 3, ніж синхронне спілкування взагалі.
Шиксин Дзенг

Відповіді:


1

Чому б вам не створити якусь функцію "Буфер", щоб отримувати всі повідомлення від асинхронних записів і обробляти їх як FIFO (перший-вхід, перший-вихід)?

Таким чином ви можете зберегти характеристики Assync своїх портів та обробити їх у режимі синхронізації.


0

у випадках, коли є лише асинхронні події, і нам потрібна синхронна відповідь, запускайте таймер або сплячіть час очікування, якщо обробник або потрібна мета досягається, тоді говорять правду, інше помилково і переконайтеся, що подія скасовується / скидається для те саме, якщо критично.


0

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

  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.