Является ли Clojure "отправить" асинхронным? - PullRequest
2 голосов
/ 15 апреля 2011

Я пишу простую сетевую среду для Clojure, используя новый пакет ввода-вывода Java .Он управляет пулом «агентов селектора», каждый из которых содержит селектор .

Я определил действие dispatch для агента селектора.Это действие блокирует вызов на selector.select().Когда это возвращается, агент выбора перебирает выбранные ключи и выполняет ввод / вывод.Когда ввод-вывод завершен, агент селектора сам отправляет действие dispatch, используя send-off, фактически зацикливаясь на вызовах selector.select().

Когда я хочу добавить новыйканал или изменить проценты канала , я отправляю агенту выбора соответствующее действие и затем разблокирую селектор (он заблокирован на select(), помните?).Это гарантирует, что (send-off selector-agent dispatch) в агенте выбора выполняется после (send selector-agent add-channel channel).


Я думал, что это будет пуленепробиваемым, поскольку вызов send-off выполняется доселектор включается и, таким образом, перед тем, как агент селектора отправляет себе действие dispatch.Однако это приводит к противоречивому поведению.Иногда сначала выполняется действие dispatch, а иногда - нет.

Насколько я понимаю, агенты не гарантируют выполнение действий в том порядке, в котором они были отправлены, когда они поступают из нескольких потоков (т. Е. * 1033).* и send-off не являются синхронными в отношении действий с очередями).

Это правильно?

Ответы [ 3 ]

6 голосов
/ 15 апреля 2011

send и send-off гарантируют, что действия будут помещены в очередь Агента в том порядке, в котором они были отправлены, в пределах одного потока.Обновление очереди агента происходит синхронно.

Я ожидаю, что у вас простое состояние гонки, хотя я не могу определить его по описанию.

1 голос
/ 15 апреля 2011

отправка и отправка созданы для асинхронных изменений состояния. если вам нужны синхронные обновления, атомы, вероятно, ваш лучший инструмент.

, поскольку вам необходимо сохранить порядок запросов, вам, возможно, придется использовать другую структуру данных внутри объекта параллелизма (атома), который может быть обновлен синхронно. Это может помочь разместить постоянную очередь внутри атома и добавить синхронность всех ваших потоков в эту очередь, в то время как ваши потребители синхронно извлекают из нее записи.

вот супер краткая схема принятия решений:

  • более одного и синхронно: используйте ссылку
  • асинхронный: используйте агент
  • асинхронный более чем один: агенты в пределах досинхронизации
  • синхронно и только одно: используйте агента.
1 голос
/ 15 апреля 2011

Вы абсолютно правы. Действия, поступающие из одного потока, будут выполняться в том же порядке, в котором они были отправлены. Но вы не можете делать какие-либо предположения о порядке выполнения действий, поступающих из разных потоков.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...