2013-03-28 50 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)))) 

如果我與電話之間有輕微的延遲,增加-VAL測試:

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

但是如果我讓所有的呼叫,以增加-VAL發生的所有一次:

(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。您可以在test-val的狀態發生變化之前在前導0中看到此內容。

原子可能更適合與鎖交互,但裁判可能是協調訪問多重身份的工具。

+0

這樣做。我曾遇到與原子和變種相同的問題,但我忘了嘗試參考。 謝謝! – crimper