6

Objective C では、さまざまなスレッドから NSMutableArray インスタンスを使用しており、@synchronized を使用してスレッド セーフにしています。現在、この配列へのすべてのアクセスは、objectAtIndex: メソッドであっても @synchronized ブロックで保護されています。それにもかかわらず、どのメソッド呼び出しを @synchronized で保護する必要があるのか​​ 疑問に思います。読み取りアクセスを保護する必要がありますか?

「ObjectAtIndex」が保護されておらず、「removeObject」と同時に呼び出された場合はどうなりますか?

すべてのメソッドが @synchronized によって保護されている場合、パフォーマンスはどうなりますか? (私は tcp/udp ゲーム サーバーを作成していますが、パフォーマンスが低下したりロックが生成されたりする場合、これらのアレイを過度に保護したくありません)。

たとえば、「containsObject:」メソッドがオブジェクトを見つけるために列挙し、別のスレッドで「removeObject:」を同時に呼び出すことは避けるべきだと思います。

おそらく良い解決策は、(読み取りアクセスと書き込みアクセス用に) あまりにも異なるロックを設定することです...

ヘルプと提案は大歓迎です!

どうもありがとう。

説明するために、以下のサンプル コードを見つけてください。

@interface TestClass : NSObject
{
    NSMutableArray * array;
}

@end

@implementation TestClass

- (id)init
{
    self = [super init];
    if (self)
    {
        array = [NSMutableArray array];
    }
    return self;
}

-(id)objectAtIndex:(NSUInteger)index
{
    @synchronized(array) **// IS IT USEFUL OR NOT ??**
    {
        return [array objectAtIndex:index];
    }
}

-(void)removeObject:(id)object
{
    @synchronized(array)
    {
        [array removeObject:object];
    }
}

-(void)compute
{
    @synchronized(array)
    {
        for (id object in array)
        {
            [object compute];
        }
    }
}

@end
4

2 に答える 2

5

はい、ミューテーションと同時に発生しないように、読み取りアクセスを同期する必要があります。ただし、読み取りアクセスは他の読み取りアクセスと同時に安全に実行できます。

複数のリーダーがある場合は、読み書きロック方式を調査する価値があります。pthread 読み取り/書き込みロック (つまりpthread_rwlock_...()) を使用できます。

または、OS X 10.7 以降および iOS 5 以降で GCD を「バリア」ルーチンとともに使用することもできます。プライベート同時キューを作成します。すべての読み取り操作を通常の方法でサブミットします (例: dispatch_sync())。などのバリア ルーチンを使用して、ミューテーション操作を送信しdispatch_barrier_async()ます。(通常、続行する前にミューテーションが完了したことを知る必要がないため、非同期にすることができます。ミューテーションを送信した後に送信されたすべての読み取りでミューテーションの結果が表示され、バリアがそれを保証することを知る必要があるだけです。 )

セッション 210 - Mastering Grand Central Dispatch の WWDC 2011 セッション ビデオにアクセスできる場合は、これについて詳しく知ることができます。

于 2013-06-15T01:29:35.183 に答える