2015-05-22 3 views
1

Вот код:Гарантируется ли заказ, когда несколько процессов ожидают ввода данных в один и тот же канал?

(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)))) 

Некоторые эксперименты в РЕПЛ предполагает, что канал принимает данные от каждого процесса 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" 

Я интересно ли порядок всегда поддерживается , то есть процесс, который начался первым, также будет подаваться на канал сначала, в каждом цикле.

ответ

2

Единственная гарантия, что заказ будет сохранен в сообщениях из одного блока go. Например, при чтении с канала вы увидите все сообщения от определенного блока go в том же порядке, который был помещен в канал этим блоком go. Однако эти сообщения могут быть переплетены с сообщениями других авторов.

В вашем конкретном примере порядок кажется детерминированным, но он вызван медленным взаимодействием человека с REPL. Когда вы вводите или вставляете код в свой REPL, блоки go начинают конкурировать за канал (и блокируются до тех пор, пока кто-то не будет готов к чтению с канала).

В качестве эксперимента можно выполнить:

(dotimes [n 10000] (println (<!! mychan))) 

и проверить, если порядок такой же. В моем РЕПЛ я получил, например:

what is this? 
msg2507 
curse2508 
reply2508 
what is this? 
msg2508 
curse2509 
reply2509 
what is this? 

Как вы можете видеть, curse2509 был до reply2509.

Смежные вопросы