2

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,但它确实完成而没有死锁。然而,当在这个 dispatch 内部时,应用程序会冻结,iOS 最终会终止应用程序。

任何帮助表示赞赏。

4

1 回答 1

1

你这有点不对。

使用dispatch_sync()将 Block 排入您已经在其上运行的串行队列可以保证死锁。

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

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

您很可能应该dispatch_async()为此使用。

于 2012-08-20T05:57:18.650 回答