キュー上のコードのブロックが、それ自体の操作dispatch_async
によって現在ブロックされている場合はどうなりますか?dispatch_sync
それらはロックされますか、dispatch_sync
それとも操作が戻った後もブロックされたキューは続行されますか?
バッキングストア(この場合はSQLite)へのアクセスを管理するオブジェクトを作成しました。1つのconcurrent
GCDキューを使用し、ストアからの情報にアクセスする他のオブジェクトは、非同期で実行されるブロックとともに要求をマネージャーに渡します。何が起こるかの本質はこれです(実際のコードではありません):
- (void) executeRequest:(StoreRequest *)request withCompletionBlock:(void(^)(NSInteger result)block{
dispatch_queue_t currentContext = dispatch_get_current_queue();
dispatch_async(_storeQueue, ^{
NSInteger result = [_store executeRequest:request];
if (block){
dispatch_async(currentContext, ^{
block(result);
}
}
});
}
実際のコードはもう少し複雑です(実際には、実行ループの最後に実行するリクエスト/ブロック/コンテキストをキューに入れて保存します)。dispatch_barrier_async
また、同時読み取り/書き込みを防ぐために書き込み要求にも使用します。これはすべて正常に機能しますが、特定の状況では、ストアで同期要求を実行する必要もあります。これで、キューに入れられた操作の前にこの要求を実行する必要はありませんが、操作が実行されるまで要求キューをブロックする必要があります。これは簡単に行うことができます。
- (NSInteger) executeRequest:(StoreRequest *)request{
__block NSInteger result = 0;
dispatch_sync(_storeQueue, ^{
result = [_store executeRequest:request];
});
return result;
}
私の質問はこれです:同期操作の前に保留中の非同期操作が、同期ディスパッチによって現在ブロックされているキューに非同期でコードのブロックをディスパッチするとどうなりますか。つまり、上記の操作は_store
キューの最後にリクエストをディスパッチして待機します。ただし、その前の操作に、待機キューへの非同期ディスパッチが含まれている可能性があります(他の操作の場合)。これはスレッドをロックしますか?キューに入れられたブロックは非同期でディスパッチされるため、_store
キューはブロックされないため終了し、理論的にはブロックしているキューを続行できます...しかし、非同期にディスパッチされたブロックで何が起こるか、またはブロックスレッドに何かをディスパッチするとロックされるかどうかはわかりません。ブロックされたキューは続行され、リクエストを完了してから保留中のブロックを処理すると想定しますが、確認したいと思います。
実際、これをすべて書いたので、うまくいくと確信していますが、とにかくこの質問を投稿して、何かを見逃していないことを確認します。