2015-05-21 93 views
1

我想知道爲什麼來自core.async通道的數據是由無限循環中的拉機制檢索到的。例如:拉而不是推core.async渠道?

user=> (def c (chan 1)) 
#'user/c 

user=> (go-loop [] 
     (let [x (<! c)] 
      (println "Got a value in this loop:" x)) 
     (recur)) 

#<ManyToManyChannel [email protected]> 

編號:https://clojuredocs.org/clojure.core.async/go-loop#example-542c88e3e4b05f4d257a297b

爲什麼沒有推機制,我可以鉤住?或者爲什麼不是這樣的循環core.async訂戶的一些實現細節? 我認爲有一個無休止的運行機制是非常消耗CPU的。這不是這種情況嗎?

回答

2

core.async/go文檔字符串說:

異步執行的身體,立即向 調用線程返回。此外,任何可見的電話!和alt!/ alt! 通道內部的操作將阻止(如果有必要)通過 '停放'調用線程而不是捆綁OS線程(或者在ClojureScript中是唯一的JS線程)。在完成 手術後,身體將恢復。 返回將接收身體的結果,當 完成

如果go當它正在等待新的消息隊列,然後循環確實是在CPU上非常浪費沒有停車的通道。但是,當go循環達到<!時,它將停止該線程,並且只有當有值從隊列中取出時纔會恢復。

+2

「勇敢而真實的Clojure」在[master.async]與master併發進程(http://www.braveclojure.com/core-async/)上有一段精彩的章節,詳細解釋了這一點。 – schaueho