1

キュー上のコードのブロックが、それ自体の操作dispatch_asyncによって現在ブロックされている場合はどうなりますか?dispatch_syncそれらはロックされますか、dispatch_syncそれとも操作が戻った後もブロックされたキューは続行されますか?

バッキングストア(この場合はSQLite)へのアクセスを管理するオブジェクトを作成しました。1つのconcurrentGCDキューを使用し、ストアからの情報にアクセスする他のオブジェクトは、非同期で実行されるブロックとともに要求をマネージャーに渡します。何が起こるかの本質はこれです(実際のコードではありません):

- (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キューはブロックされないため終了し、理論的にはブロックしているキューを続行できます...しかし、非同期にディスパッチされたブロックで何が起こるか、またはブロックスレッドに何かをディスパッチするとロックされるかどうかはわかりません。ブロックされたキューは続行され、リクエストを完了してから保留中のブロックを処理すると想定しますが、確認したいと思います。

実際、これをすべて書いたので、うまくいくと確信していますが、とにかくこの質問を投稿して、何かを見逃していないことを確認します。

4

2 に答える 2

1

dispatch_asyncブロックすることはありません。とても簡単です。

于 2013-03-21T14:52:23.357 に答える
1

dispatch_async自体がブロックすることはありません。ブロックをキューの最後に追加し、すぐに戻ります。

ブロックは実行されますか?場合によります。シーケンシャルキューでは、1つのブロックがブロックされている場合、そのブロックがブロック解除されて終了するまで、他のブロックは実行されません。バックグラウンドキューでは、キューは複数のスレッドを使用できるため、一部のブロックがブロックされている場合でも、他のブロックを開始するだけです。ブロックされたブロックの数に制限があるかどうかは試していませんが、ブロックされていないすべてのブロックが最終的に実行されて終了し、ブロックされたブロックが残る可能性があります。

于 2014-06-23T12:14:30.903 に答える