{
dispatch_queue_t myQueue = dispatch_queue_create("com.mycompany.myqueue", 0);
dispatch_sync(myQueue, ^{
//Do EXTREME PROCESSING!!!
for (int i = 0; i< 100; i++) {
[NSThread sleepForTimeInterval:.05];
NSLog(@"%i", i);
}
dispatch_sync(dispatch_get_main_queue(), ^{
[self updateLabelWhenBackgroundDone];
});
});
}
我在这里陷入僵局。根据Apple文档
“dispatch_sync”:“将块提交到调度队列以进行同步 执行。与dispatch_async不同,此函数直到返回为止 块已经完成。调用此功能并定位 当前队列导致死锁。“。
但是,我在dispatch_sync
上执行外部myQueue
,然后在另一个名为“main_queue”的队列中执行内部ditpatch_sync
。
无法找出死锁的原因。任何评论/帮助都在这里赞赏。
答案 0 :(得分:10)
如果像这样调度_sync到myQueue并且调用发生在主线程上,那么dispatch_sync将尽可能在那里执行块,而不是像dispatch_async那样在新的工作线程上执行。您无法保证为您的队列获得单独的工作线程。
然后该块在主线程上运行,直到它遇到第二个dispatch_sync调用,该调用恰好以主队列为目标。该队列无法提供服务,因为已经有一个块在运行,这就是你最终陷入僵局的地方。
如果这是您的问题,即第一个dispatch_sync确实来自主线程,那么您应该切换到dispatch_async。您不希望使用长时间运行的“EXTREME PROCESSING”操作来阻止主线程。
答案 1 :(得分:5)
您正在拨打dispatch_sync
两次。第一次挂起主线程等待您的块完成。然后该块使用第二个调用挂起后台线程,该第二个调用尝试回送到主线程(由于它被挂起,它将永远不会从其队列中处理该块)。两个线程现在都在互相等待。
至少有一个电话需要dispatch_async
。
答案 2 :(得分:2)
我有类似的问题,这些解决方案都没有奏效。我问过比我聪明的人。
我的问题是我正在派遣一个异步工作块,然后显示一个进度窗口。通过
回调主线程dispatch_sync(dispatch_get_main_queue(),^ {})
失败,异步调用失败。
解释是主线程不再处于公共模式&#39;因为模态窗口。我用这个替换了我对主线程的调用....
CFRunLoopPerformBlock(([[NSRunLoop mainRunLoop] getCFRunLoop]), (__bridge CFStringRef)NSModalPanelRunLoopMode, ^{
//Update UI thread.
});