我有很多工人在跑,把工作物品从队列中拉下来。类似于:
(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中有很大的领导空间,所以工人们应该可以把工作从队列中拿出来。
我的问题:
发布于 2015-12-11 18:14:28
当我修复代码的缩进时,我看到的是:
(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))
)) ;; These parens don't balance.忽略额外的父类,我假设这是一些复制/粘贴错误,下面是一些观察:
num-started,但在创建该线程后立即将其减少到go线程之外。很有可能,递减总是发生在增量之前。请记住,生成go线程并不意味着当前线程(执行dotimes的生成线程)将被阻塞。我可能弄错了,但看起来您的代码似乎是在假设(swap! num-started dec)只在紧接其上面生成的go线程完成时才会运行。但这不是真的,即使go线程最终完成了(正如上面提到的,它们没有完成)。
发布于 2016-01-06 03:33:52
go例程完成的工作不应该执行任何IO或阻塞操作(比如线程/睡眠),因为所有go例程都共享相同的线程池,而线程池现在有固定大小的2+ 42。对于IO有界的工作,请使用核心.异步/线程。
请注意,线程池限制了并发执行的go例程的数量,但您可以有大量等待执行的例程。
比方说,如果您启动Chrome、Vim和iTunes (相当于3个go例程),但您的笔记本中只有一个CPU (相当于大小为1的线程池),那么它们中只有一个将在CPU中执行,另一个将等待执行。它是负责暂停/恢复程序的操作系统,所以看起来它们都在同时运行。Core.async只是做了同样的事情,但是由于core.async可以在它们命中a!时暂停运行例程。
现在回答你的问题:
希望能帮上忙。
https://stackoverflow.com/questions/34220873
复制相似问题