8

マルチスレッド アクセサーの GCD ベースのパターンに移行するかどうかを検討しています。私は何年もの間、アクセサーでカスタムロックベースの同期を使用してきましたが、いくつかの情報 ( Intro to GCD ) を見つけて、GCD ベースのアプローチの長所があるようです。ここで対話を開始して、自分自身と他の人が決定を検討するのを助けることを望んでいます.

パターンは次のようになります。

- (id)something
{
    __block id localSomething;
    dispatch_sync(queue, ^{
        localSomething = [something retain];
    });
    return [localSomething autorelease];
}

- (void)setSomething:(id)newSomething
{
    dispatch_async(queue, ^{
        if(newSomething != something)
        {
            [something release];
            something = [newSomething retain];
            [self updateSomethingCaches];
        }
    });
}

プロの側では、おそらく非ブロック書き込みアクセスの利点が得られます。ロックよりも低いオーバーヘッド (おそらく?); 重要なコード セクションから戻る前にロックを解除するのを忘れないための安全性。他?

短所: 例外処理が存在しないため、必要なすべてのブロックにこれをコーディングする必要があります。

このパターンは、マルチスレッド アクセサーを記述する方法として推奨される可能性がありますか?

この目的でディスパッチ キューを作成するための標準的な方法はありますか? 言い換えれば、粒度をトレードオフするためのベストプラクティスは? たとえば、ロックを使用すると、各アトリビュートをロックすると、オブジェクト全体をロックするよりも粒度が細かくなります。ディスパッチ キューでは、すべてのオブジェクトに対して 1 つのキューを作成するとパフォーマンスのボトルネックが生じると想像できましたが、オブジェクトごとのキューは適切でしょうか? 明らかに、答えは特定のアプリケーションに大きく依存しますが、アプローチの実現可能性を評価するのに役立つ既知のパフォーマンスのトレードオフがあります。

情報/洞察をいただければ幸いです。

4

1 に答える 1

8

このパターンは、マルチスレッド アクセサーを記述する方法として推奨される可能性がありますか?

シリアルキューを念頭に置いて書いたと思いますが、その理由はありません。このことを考慮:

dispatch_queue_t queue = dispatch_queue_create("com.example", DISPATCH_QUEUE_CONCURRENT);

// same thing as your example
- (NSString*)something {
    __block NSString *localSomething;
    dispatch_sync(queue, ^{
        localSomething = _something;
    });
    return localSomething;
}

- (void)setSomething:(NSString*)something {
    dispatch_barrier_async(queue, ^{
        _something = something;
    });
}

同時に読み取りますが、ディスパッチ バリアを使用して書き込み中の同時実行を無効にします。GCD の大きな利点は、@property (アトミック) のようにオブジェクト全体をロックする代わりに、同時読み取りを許可することです。

両方の非同期 (dispatch_async、dispatch_barrier_async) は、クライアントの観点からは高速ですが、ブロックをコピーする必要があり、ブロックのタスクが非常に小さいため、同期よりも実行が遅くなります。コピーにかかる時間は意味のあるものになります。私はむしろクライアントに早く戻ってきてもらいたいので、それで問題ありません。

于 2013-04-07T01:56:03.203 に答える