2013-03-28 2 views
3

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

Вот пример:

(def test-val (agent 0)) 
(def allow-update (agent true)) 

(defn increase-val [] 
    (locking allow-update 
    (when @allow-update 
     (send allow-update (fn [_ x] x) false) 
     (send test-val + 1))) 
    (print @test-val)) 

(defn run-futures [delay-time] 
    (send allow-update (fn [_ x] x) true) 
    (send test-val * 0) 
    (dotimes [_ 20] 
    (Thread/sleep delay-time) 
    (future (increase-val)))) 

Если я проверить это с небольшой задержкой между вызовами увеличения-валин:

(run-futures 2) 
;outputs 0111111111111111111 every time, as expected 

Но если я позволяю все вызовы к увеличению-валин случиться все разом:

(run-futures 0) 
;001222222222222222 
(run-futures 0) 
;000000145555555555 
(run-futures 0) 
;000000013677777777 

Кажется, что замок не успевает включиться, поэтому агент увеличивается несколькими фьючерсами.

Я надеюсь, что у меня что-то отсутствует, что позволит мне убедиться, что я не действую на дублированных одновременных мероприятиях.

Спасибо!

+0

Вы могли бы включить определение test-val? Я предполагаю, что это агент? –

+0

кричит, исправил это. – crimper

ответ

2

Поскольку Агенты являются асинхронными и нескоординированными, может произойти задержка между отправкой им сообщения и фактическим запуском отправленного действия. Во время этой задержки для большинства или всех вызовов можно звонить (send test-val + 1), чтобы пройти через заблокированную секцию до того, как первая будет выполняться, и установите @ allow-update на false. Вы можете увидеть это в начале 0, прежде чем состояние тестового значения изменится.

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

+0

Это сделало. У меня была такая же проблема с атомами и vars, но я забыл попробовать refs. Спасибо! – crimper

Смежные вопросы