首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >监测戈鲁丁和渠道泄漏/饥饿?

监测戈鲁丁和渠道泄漏/饥饿?
EN

Stack Overflow用户
提问于 2015-12-11 10:08:12
回答 2查看 292关注 0票数 1

我有很多工人在跑,把工作物品从队列中拉下来。类似于:

代码语言:javascript
复制
(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-upnum-workers中有很大的领导空间,所以工人们应该可以把工作从队列中拿出来。

我的问题:

  1. 我能做些什么让这件事更有力吗?
  2. 还有什么其他的诊断方法可以用来找出出什么问题了吗?有没有办法监控目前正在工作的猩猩数量,以防它们死亡?
  3. 你能使观测结果与数据相吻合吗?
EN

回答 2

Stack Overflow用户

发布于 2015-12-11 18:14:28

当我修复代码的缩进时,我看到的是:

代码语言:javascript
复制
(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.

忽略额外的父类,我假设这是一些复制/粘贴错误,下面是一些观察:

  1. 在go线程中增加num-started,但在创建该线程后立即将其减少到go线程之外。很有可能,递减总是发生在增量之前。
  2. 您创建的100个循环(每个go线程一个)永远不会终止。这本身并不是一个问题,只要这是有意的和故意的。

请记住,生成go线程并不意味着当前线程(执行dotimes的生成线程)将被阻塞。我可能弄错了,但看起来您的代码似乎是在假设(swap! num-started dec)只在紧接其上面生成的go线程完成时才会运行。但这不是真的,即使go线程最终完成了(正如上面提到的,它们没有完成)。

票数 0
EN

Stack Overflow用户

发布于 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!时暂停运行例程。

现在回答你的问题:

  1. 不是的。尝试/捕捉所有异常是您的最佳选择。此外,监视队列的大小。我会重新评估core.async的需求。扎克·特尔曼( Zach )有一个非常好的线程池实现,它有很多度量标准。
  2. 线程转储将显示所有core.async线程的阻塞位置,但正如我所说,您不应该在常规线程中执行任何IO工作。看看核心.异步/管道阻塞
  3. 如果您有4个内核,您将得到一个50的core.async线程池,这与您对50个并发go块的观察结果相匹配。其他50个go块正在运行,但要么等待工作出现在队列中,要么等待执行一个时隙。请注意,它们都有机会在num-started is 100中至少执行一次。

希望能帮上忙。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34220873

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档