【发布时间】:2016-03-17 05:01:00
【问题描述】:
我有许多工作人员正在运行,将工作项目从队列中拉出。比如:
(def num-workers 100)
(def num-tied-up (atom 0))
(def num-started (atom 0))
(def input-queue (chan (dropping-buffer 200))
(dotimes [x num-workers]
(go
(swap num-started inc)
(loop []
(let [item (<! input-queue)]
(swap! num-tied-up inc)
(try
(process-f worker-id item)
(catch Exception e _))
(swap! num-tied-up dec))
(recur)))
(swap! num-started dec))))
希望num-tied-up 代表在给定时间点执行工作的工人数量。 num-tied-up 的值徘徊在相当一致的50 附近,有时是60。由于num-workers 为100,num-started 的值正如预期的那样为100(即所有go 例程都在运行),这感觉就像有一个舒适的余量。
我的问题是input-queue 正在增长。我预计它会徘徊在零标记附近,因为有足够的工人从它上面取下物品。但在实践中,最终它会最大化并丢弃事件。
看起来tied-up 在num-workers 中有足够的空间,所以工作人员应该可以从队列中取出工作。
我的问题:
- 我能做些什么来使它更健壮吗?
- 是否有任何其他诊断程序可以用来找出问题所在?有没有办法监控当前工作的 goroutines 的数量,以防它们死亡?
- 您能否使观察结果与数据相符?
【问题讨论】:
-
go使用 2*NPROCS+42 的固定大小的线程池。你有4核吗?如果您想要未绑定或其他绑定,则可以手动生成线程。 -
我认为
go例程是线程之上的轻量级进程,所以线程池的大小与go例程的数量没有直接关系?也许我误解了这一点。无论如何,我正在寻找为什么会发生这种行为的解释。 -
您必须向我们展示将值推送到输入队列的代码。由于生产者比(50)个消费者快,它的价值正在下降。我只是使用阻塞缓冲区来同步生产/消费。
-
有 100 个消费者。似乎只有 50 个在工作。其他 50 人怎么了?
-
由于
core.async的限制,你只有50个go块并发运行。
标签: clojure core.async