简体   繁体   English

换能器如何在core.async通道中执行?

[英]How are transducers executed in core.async channels?

When making a channel a channel like so: 将频道设置为类似频道时:

(chan 10 tx)

If i created 10 channels like this and then sent a message to all at the same time, how would the transducers be executed. 如果我创建了10个这样的通道,然后同时向所有通道发送一条消息,那么如何执行换能器。 Would they run concurrent or on one thread? 它们将同时运行还是在一个线程上运行?

I think that right now the behaviour of when the transducer is run is not defined, but looking at the implementation of ManyToManyChannel , the transducer (which is the add! field) can be called both when writing and reading from the channel. 我认为,现在还没有定义换能器运行时的行为,而是查看ManyToManyChannel的实现,可以在从通道进行写入和读取时调用换能器(即add!字段)。

Running a simple test seems that if the channel is not full, the writing thread will execute the transducer, but if the channel is full, sometimes the reading thread runs it. 运行一个简单的测试似乎表明,如果通道未满,则写线程将执行换能器,但是如果通道已满,则有时读取线程将运行它。

A sample with a small buffer: 带有小缓冲区的样本:

(defn thread-name []
  (.getName (Thread/currentThread)))

(require '[clojure.core.async :as async :refer [chan <! >! >!! go]])

(defn p [& args]
  (locking *out*
          (apply println (thread-name) ":" args)))

(defn log [v]
  (p "Transforming" v)
  v)

(def tx (map log))

(def c (chan 1 tx))
(def c2 (chan 1 tx))

(go
  (loop []
    (when-let [v (<! c)]
      (p "Getting from c1" v)
      (<! (async/timeout 100))
      (recur))))

(go
  (loop []
    (when-let [v (<! c2)]
      (p "Getting from c2" v)
      (<! (async/timeout 100))
      (recur))))

(dotimes [_ 5]
  (p "Putting in c1" 1)
  (>!! c 1)
  (p "Putting in c2" 100)
  (>!! c2 100))

Produces the output: 产生输出:

nREPL-worker-20 : Transforming 1
nREPL-worker-20 : Putting in c2 100
async-dispatch-33 : Getting from c1 1
nREPL-worker-20 : Transforming 100
nREPL-worker-20 : Putting in c1 1
async-dispatch-31 : Getting from c2 100
nREPL-worker-20 : Transforming 1
nREPL-worker-20 : Putting in c2 100
nREPL-worker-20 : Transforming 100
nREPL-worker-20 : Putting in c1 1
async-dispatch-35 : Getting from c2 100
async-dispatch-34 : Transforming 1 <---- In this case is run in the reading side
async-dispatch-34 : Getting from c1 1
nREPL-worker-20 : Putting in c2 100
nREPL-worker-20 : Transforming 100
async-dispatch-37 : Getting from c2 100
async-dispatch-36 : Getting from c1 1
nREPL-worker-20 : Putting in c1 1

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM