Reputation: 23134
Here is the code:
(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))))
Some experimentation in the repl suggests that the channel takes data from each of the 4 process in turn:
(<!! 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"
I am wondering whether the order is always maintained, i.e. the process that started first will also feed to channel first, in each cycle.
Upvotes: 1
Views: 162
Reputation: 13185
The only guarantee is that the order will be preserved within messages from a single go
block. For example, when reading from the channel you will see all messages from a certain go
block in the same order they were put to the channel by that go
block. However, those messages might be interwoven with messages from other writers.
In your particular example, the order seems to be deterministic but it is caused by the slow human interaction with the REPL. When you type or paste the code to your REPL, the go
blocks start competing for the channel (and they block until there is someone ready to read from the channel).
As an experiment you might execute:
(dotimes [n 10000] (println (<!! mychan)))
and check if the order is the same. In my REPL I got for example:
what is this?
msg2507
curse2508
reply2508
what is this?
msg2508
curse2509
reply2509
what is this?
As you can see, curse2509
came before reply2509
.
Upvotes: 2