Я пишу простую сетевую среду для 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
не являются синхронными в отношении действий с очередями).
Это правильно?