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発生しますが、デッドロックなしで完了します。ただし、このディスパッチ内では、アプリがフリーズし、iOSは最終的にアプリを終了します。

どんな助けでも大歓迎です。

4

1 に答える 1

1

これは少し間違っています。

dispatch_sync()すでに実行しているシリアルキューにブロックをエンキューするために使用すると、デッドロックが発生することが保証されます。

すでに実行している並行dispatch_sync()キューにブロックをエンキューするために使用すると、デッドロックが発生する可能性が非常に高くなります。同期ブロックをほぼ即座にデキューするキューに依存しています。これは、使用可能なリソースに応じて発生する場合と発生しない場合があります。

また、キューによって提供される並行性の性質を誤解しているようです。並行キューに送信[self.networkQueue cancelAllOperations];しても、速度は向上しません。そのメソッド呼び出しは、キュー上のさまざまな作業単位にスライスされません。代わりに、送信したブロック全体(3行すべて)がキューの1つのユニットになります。送信する他のブロックと同時に実行される場合がありますが、それ自体で同時実行性を利用することはできません。自分で作業を分割し、各ユニットを個別のブロックとして送信する必要があります。たとえば、cancelの各操作に送信します。NSOperationQueue

ほとんどの場合dispatch_async()、これに使用する必要があります。

于 2012-08-20T05:57:18.650 に答える