为什么这个GCD操作导致死锁?

时间:2012-08-20 04:56:13

标签: objective-c multithreading asihttprequest grand-central-dispatch

我知道如果你从同一个串行队列上的另一个sync调度调用sync调度,就会发生死锁,但这是我听说过的GCD死锁的唯一“已知”原因。

我正在使用全局并发队列,所以我希望sync请求不会导致死锁。我有这个代码,它正在使用ASIHTTPRequest

dispatch_sync(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{

[self.networkQueue cancelAllOperations];

self.networkQueue=nil;

self.networkQueue=[ASINetworkQueue queue];
});

我的想法是尝试加快cancelAllOperations部分的速度,因为如果networkQueue中有数千个操作可能会花费很长时间。

但是当我调用此代码时,会发生死锁。如果我从GCD中取出这个块并在主线程上运行它,那么cancelAllOperations运行时会出现延迟,但它会在没有死锁的情况下完成。但是,在此调度内部,应用程序冻结,iOS最终会终止该应用程序。

感谢任何帮助。

1 个答案:

答案 0 :(得分:1)

你有点错误。

使用dispatch_sync()将Block排入已运行的串行队列,确保死锁。

使用dispatch_sync()将阻止队列入已运行的并发队列,很可能死锁。您依赖队列几乎立即使同步块出列,这可能会也可能不会发生,具体取决于可用资源。

您似乎也误解了队列提供的并发性质。将[self.networkQueue cancelAllOperations];提交到并发队列不会加快速度 - 该方法调用不会被分成队列中的各种工作单元。相反,您提交的整个块 - 全部三条线 - 都是队列的一个单元。它可以与您提交的其他块同时运行,但它不能本身利用任何并发性。您必须自己拆分工作并将每个单元作为单独的块提交 - 例如,将cancel发送到NSOperationQueue上的每个操作。

您最有可能正在使用dispatch_async()