GCD调度并发队列冻结,并在崩溃日志中显示“已达到调度线程软限制:64" [英] GCD dispatch concurrent queue freeze with 'Dispatch Thread Soft Limit Reached: 64' in crash log
问题描述
我的程序是一个处理传入请求的服务器.每个有效的请求都包装在NSOperation
中,并传递给普通的NSOperationQueue
.
My program is a server which handles incoming requests. Each valid request is wrapped in NSOperation
and passed to a normal NSOperationQueue
.
每个NSOpearation
处理其请求.在某些情况下,在NSDictionary
上存在争用,我使用dispatch_queue
(并发队列),dispatch_barrier_async
(在设置值时)和dispatch_sync
(在获取值时)使此NSDictionary
线程安全.
Each NSOpearation
processes its request. In some cases, there is contention at a NSDictionary
which I use dispatch_queue
(concurrent queue), dispatch_barrier_async
(when set value) and dispatch_sync
(when get value) to make this NSDictionary
thread-safe.
我同时测试100个请求的程序,然后有时冻结.我用SIGSEGV
杀死了进程以查看崩溃日志.
I test my program with 100 requests concurrently then the process freezes sometimes. I kill the process with SIGSEGV
to see crash log.
大多数线程停留在此队列的dispatch_sync
.并且在下面有一个注释
Most of the threads stuck at dispatch_sync
of this queue. And there is a note below
已达到调度线程软限制:64(调度线程太多 在同步操作中被阻止)
Dispatch Thread Soft Limit Reached: 64 (too many dispatch threads blocked in synchronous operations)
此注释的真正含义是什么?它的行为是什么?我找不到有关此限制的信息.我该如何解决这个问题?
What does this note really mean? What is its behavior? I cannot find information about this limit. How can I fix this issue?
我可以想出两种可能的方法来避免此问题. (我将对其进行测试,稍后会更新)
I can think of 2 possible ways to avoid this problem. (which I'm going to test them and will update later)
- 使用
dispatch_semaphore
限制将块提交到此并发队列. - 限制
NSOperationQueue
的maxConcurrentOperationCount
- Use
dispatch_semaphore
to limit submitting the block to this concurrent queue. - Limit
maxConcurrentOperationCount
of theNSOperationQueue
您有更好的解决方案吗?
Do you have a better solution?
推荐答案
我可以想到两种避免该问题的方法. (我将对其进行测试,稍后会更新)
I can think of 2 possible ways to avoid this problem. (which I'm going to test them and will update later)
- 使用
dispatch_semaphore
限制将块提交到此并发队列. - 限制
NSOperationQueue
中的maxConcurrentOperationCount
.
- Use
dispatch_semaphore
to limit submitting the block to this concurrent queue. - Limit
maxConcurrentOperationCount
of theNSOperationQueue
.
是的,这是两种常见的模式.为了将来的读者起见,解决耗尽工作线程"问题的另一种解决方案是Objective-C的dispatch_apply
,在Swift中也称为concurrentPerform
,它允许并发操作不会耗尽您的资源.工人线程.但这实际上仅适用于预先启动一系列任务(例如,您要并行化for
循环),而不是您在问题中概述的方案.但是,据记录,dispatch_apply
/concurrentPerform
是解决此一般问题的第三个常见解决方案.
Yes, those are two common patterns. For the sake of future readers, the other solution to this "exhausting worker threads" problem is Objective-C's dispatch_apply
, also known as concurrentPerform
in Swift, which allows concurrent operations in a manner that won’t exhaust your pool of worker threads. But that’s really only applicable when launching a whole series of tasks up front (e.g. you want to parallelize a for
loop), not the scenario you outline in your question. But, still, for the record, dispatch_apply
/concurrentPerform
is the third common solution for this general problem.
我找不到有关此限制的信息.
I cannot find information about this limit.
过去在WWDC 2012视频异步设计模式使用Blocks,GCD和XPC ,但该视频不再可用(奇怪的是其他WWDC 2012视频,但不是那个).但是他们确实解决了WWDC 2015视频建筑带有GCD的高效响应式应用程序.
This used to be covered really nicely in WWDC 2012 video Asynchronous Design Patterns with Blocks, GCD, and XPC, but that video is no longer available (other WWDC 2012 videos are, but not that one, curiously). But they do walk through the limited worker thread issue in WWDC 2015 video Building Responsive and Efficient Apps with GCD.
这篇关于GCD调度并发队列冻结,并在崩溃日志中显示“已达到调度线程软限制:64"的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!