qed
qed

Reputation: 23134

Is order guaranteed when multiple processes are waiting to put data in the same channel?

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

Answers (1)

Piotrek Bzdyl
Piotrek Bzdyl

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

Related Questions