3

Grand Central Dispatch(GCD)を使用して、リソースへのアクセスを制御する同時読み取り専用書き込みモデルを実装する適切な方法を理解しようとしています。

頻繁に読み取られ、たまに更新されるNSMutableDictionaryがあるとします。読み取りが常に辞書の一貫した状態で機能することを保証する適切な方法は何ですか?確かに、キューを使用して、ディクショナリへのすべての読み取りおよび書き込みアクセスをシリアル化できますが、それでは、ディクショナリへの同時アクセスを許可する必要がある読み取りが不必要にシリアル化されます。最初、ここでのグループの使用は有望に聞こえます。'read'グループを作成し、それにすべての読み取り操作を追加することができます。これにより、読み取りを同時に行うことができます。そして、更新を行うときが来たら、書き込み操作の一部としてdispatch_notify()またはdispatch_wait()を実行して、更新を続行する前にすべての読み取りが完了していることを確認できます。しかし、書き込み操作が完了するまで後続の読み取り操作が開始されないようにするにはどうすればよいですか?

上記の辞書の例を次に示します
。R1:0秒で、読み取りが完了し、5秒で完了します
。R2:2秒で、別の読み取りが完了し、5秒で完了します
。W1:4秒で、書き込み操作が実行されます。辞書に3秒間アクセスする必要があります
R3:6秒で別の読み取りが行われ、完了するまでに5秒かかります
W2:8秒で、別の書き込み操作が行われ、完了するまでに3秒かかります

理想的には、上記は次のように再生されます
。R1は0秒で始まり、5で終わります
R2は2秒で始まり、7で終わります
W1は7秒で始まり、10で終わります
R3は10秒で始まり、15で終わります
W2は15秒で始まります、18で終了

注:R3は6秒で到着しましたが、W1が早く到着したため、W1より前に開始することはできませんでした。

GCDで上記を実装するための最良の方法は何ですか?

4

1 に答える 1

3

あなたは正しい考えを持っていると思います。概念的には、「バリア」ブロックを送信できるプライベート並行キューが必要です。これにより、バリアブロックは、以前に送信されたすべてのブロックの実行が終了するまで待機し、すべてを単独で実行します。

GCDは(まだ?)この機能をすぐに提供しませんが、読み取り/書き込み要求をいくつかの追加ロジックでラップし、これらの要求を中間のシリアルキューに送ることでシミュレートできます。

読み取り要求がシリアルキューの先頭に到達するとdispatch_group_async、実際にはグローバル同時キューに作用します。書き込み要求の場合はdispatch_suspend、シリアルキューを作成dispatch_group_notifyし、前の要求の実行が終了した後でのみ、呼び出して同時キューに作業を送信する必要があります。この書き込み要求が実行された後、キューを再開します。

次のようなものがあなたを始めることができます(私はこれをテストしていません):

dispatch_block_t CreateBlock(dispatch_block_t block, dispatch_group_t group, dispatch_queue_t concurrentQueue) {
    return Block_copy(^{ 
        dispatch_group_async(concurrentQueue, group, block);
    });
}

dispatch_block_t CreateBarrierBlock(dispatch_block_t barrierBlock, dispatch_group_t group, dispatch_queue_t concurrentQueue) {
    return Block_copy(^{
        dispatch_queue_t serialQueue = dispatch_get_current_queue();
        dispatch_suspend(serialQueue);
        dispatch_group_notify(group, concurrentQueue, ^{
            barrierBlock();
            dispatch_resume(serialQueue);
        });
    });
}

dispatch_asyncを使用して、これらのラップされたブロックをシリアルキューにプッシュします。

于 2011-05-05T12:00:08.730 に答える