【问题标题】:GCD dispatch concurrent queue freeze with 'Dispatch Thread Soft Limit Reached: 64' in crash logGCD 调度并发队列冻结,崩溃日志中出现“已达到调度线程软限制:64”
【发布时间】:2012-12-11 06:11:50
【问题描述】:

我的程序是一个处理传入请求的服务器。每个有效请求都包含在NSOperation 中并传递给普通的NSOperationQueue

每个NSOpearation 处理它的请求。在某些情况下,NSDictionary 存在争用,我使用dispatch_queue(并发队列)、dispatch_barrier_async(设置值时)和dispatch_sync(获取值时)使NSDictionary 线程安全。

我同时使用 100 个请求测试我的程序,然后进程有时会冻结。我用SIGSEGV 终止进程以查看崩溃日志。

大多数线程卡在此队列的dispatch_sync。并且下面有注释

已达到调度线程软限制:64(调度线程过多 在同步操作中被阻塞)

这个注释的真正含义是什么?它的行为是什么?我找不到有关此限制的信息。我该如何解决这个问题?

我可以想到 2 种可能的方法来避免这个问题。 (我将对其进行测试并稍后更新)

  1. 使用dispatch_semaphore 限制将块提交到此并发队列。
  2. 限制maxConcurrentOperationCountNSOperationQueue

你有更好的解决方案吗?

【问题讨论】:

  • 这个问题应该有助于解释一下:stackoverflow.com/questions/7213845/…
  • 您的解决方案基本上是正确的。如果必须在并发队列中进行阻塞工作,则需要限制允许的并行量。 libdispatch 只会对 cpu-bound 工作进行自我限制。
  • 我得到与“setMaxConcurrentOperationCount :NSOperationQueueDefaultMaxConcurrentOperationCount”相同的错误。
  • @Stephane 是的,您想将其设置为某个固定数字,以使您低于最大工作线程数。

标签: multithreading grand-central-dispatch


【解决方案1】:

我可以想到 2 种可能的方法来避免这个问题。 (我将对其进行测试并稍后更新)

  1. 使用dispatch_semaphore 限制将块提交到此并发队列。
  2. 限制maxConcurrentOperationCountNSOperationQueue

是的,这是两种常见的模式。为了未来的读者,这个“耗尽工作线程”问题的另一个解决方案是 Objective-C 的dispatch_apply,在 Swift 中也称为concurrentPerform,它允许以不会耗尽你的池的方式进行并发操作工作线程。但这实际上只适用于预先启动一系列任务(例如,您想要并行化 for 循环),而不是您在问题中概述的场景。但是,据记录,dispatch_apply/concurrentPerform 是解决这个一般问题的第三种常见解决方案。

我找不到有关此限制的信息。

这曾经在 WWDC 2012 视频Asynchronous Design Patterns with Blocks, GCD, and XPC 中得到很好的介绍,但该视频不再可用(奇怪的是,其他 WWDC 2012 视频有,但不是那个)。但他们确实在 WWDC 2015 视频Building Responsive and Efficient Apps with GCD 中解决了有限的工作线程问题。

【讨论】:

    猜你喜欢
    • 2017-07-20
    • 1970-01-01
    • 2016-07-13
    • 1970-01-01
    • 2011-12-04
    • 2015-03-12
    • 1970-01-01
    • 2016-04-05
    • 2018-02-25
    相关资源
    最近更新 更多