最近、特定のシリアルディスパッチキューで特定のブロックの同期実行を保証するために使用できる関数が必要になりました。この共有関数は、そのキューですでに実行されているものから呼び出される可能性があるため、同じキューへの同期ディスパッチによるデッドロックを防ぐために、このケースを確認する必要がありました。
私はこれを行うために次のようなコードを使用しました:
void runSynchronouslyOnVideoProcessingQueue(void (^block)(void))
{
dispatch_queue_t videoProcessingQueue = [GPUImageOpenGLESContext sharedOpenGLESQueue];
if (dispatch_get_current_queue() == videoProcessingQueue)
{
block();
}
else
{
dispatch_sync(videoProcessingQueue, block);
}
}
この関数は、を使用して、dispatch_get_current_queue()
この関数が実行されているキューのIDを判別し、それをターゲットキューと比較します。一致するものがある場合は、関数がすでに実行されているため、そのキューにディスパッチせずにブロックをインラインで実行することを認識しています。
このような比較を行うために使用することが適切であるかどうかについて矛盾することを聞いたことがdispatch_get_current_queue()
あり、ヘッダーに次の表現があります。
デバッグとロギングの目的でのみ推奨:
それがグローバルキューの1つであるか、コード自体が作成したキューでない限り、コードは返されたキューについていかなる仮定もしてはなりません。そのキューがdispatch_get_current_queue()によって返されるキューでない場合、コードはキューへの同期実行がデッドロックから安全であると想定してはなりません。
さらに、iOS 6.0(ただし、Mountain Lionではまだ)では、GCDヘッダーがこの関数を非推奨としてマークするようになりました。
この機能をこのように使うべきではないように思えますが、代わりに何を使うべきかわかりません。メインキューを対象とした上記のような関数の場合、を使用できます[NSThread isMainThread]
が、デッドロックを防ぐために、カスタムシリアルキューの1つで実行されているかどうかを確認するにはどうすればよいですか?