多个进程在同一个通道等待放数据时,顺序是否有保证?
Is order guaranteed when multiple processes are waiting to put data in the same channel?
代码如下:
(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"
我想知道顺序是否始终保持不变,即在每个周期中,先启动的进程也会先馈送到通道。
唯一的保证是顺序将保留在来自单个 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
之前。
代码如下:
(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"
我想知道顺序是否始终保持不变,即在每个周期中,先启动的进程也会先馈送到通道。
唯一的保证是顺序将保留在来自单个 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
之前。