以下是代码:
(ns typedclj.core
(:require [clojure.core.async
:as a
:refer [>! <! >!! <!! go chan buffer close! thread
alts! alts!! timeout]])
(:gen-class))
(def mychan (chan))
(go (while true
(>! mychan "what is this?")))
(go (loop [i 0]
(>! mychan (str "msg" i))
(recur (inc i))))
(go (loop [i 0]
(>! mychan (str "reply" i))
(recur (inc i))))
(go (loop [i 0]
(>! mychan (str "curse" i))
(recur (inc i))))
repl中的一些实验表明,通道依次从4个过程中的每一个中获取数据:
(<!! mychan)
=> "what is this?"
(<!! mychan)
=> "msg0"
(<!! mychan)
=> "reply0"
(<!! mychan)
=> "curse0"
(<!! mychan)
=> "what is this?"
(<!! mychan)
=> "msg1"
(<!! mychan)
=> "reply1"
(<!! mychan)
=> "curse1"
(<!! mychan)
=> "what is this?"
(<!! mychan)
=> "msg2"
(<!! mychan)
=> "reply2"
(<!! mychan)
=> "curse2"
我想知道订单是否始终保持不变,即首先开始的流程也将在每个周期中首先进入通道。
答案 0 :(得分:2)
唯一的保证是订单将保留在来自单个go
块的消息中。例如,当您从频道中进行阅读时,您将看到来自某个go
块的所有消息,其顺序与go
块放入频道的顺序相同。但是,这些消息可能与其他作者的消息交织在一起。
在您的特定示例中,顺序似乎是确定性的,但它是由人与REPL的缓慢交互引起的。当您将代码键入或粘贴到REPL时,go
块开始竞争通道(并且它们会阻塞,直到有人准备从通道读取)。
作为实验,您可以执行:
(dotimes [n 10000] (println (<!! mychan)))
并检查订单是否相同。在我的REPL中,我得到了例如:
what is this?
msg2507
curse2508
reply2508
what is this?
msg2508
curse2509
reply2509
what is this?
如您所见,curse2509
出现在reply2509
之前。