Objective-C で @synchronized はどのようにロック/ロック解除されるのでしょうか? 質問する

Objective-C で @synchronized はどのようにロック/ロック解除されるのでしょうか? 質問する

@synchronized は相互排他を実現するために「ロック」と「ロック解除」を使用しませんか? その場合、ロック/ロック解除はどのように行うのですか?

次のプログラムの出力は「Hello World」のみです。

@interface MyLock: NSLock<NSLocking>
@end

@implementation MyLock

- (id)init {
    return [super init];
}

- (void)lock {
    NSLog(@"before lock");
    [super lock];
    NSLog(@"after lock");
}

- (void)unlock {
    NSLog(@"before unlock");
    [super unlock];
    NSLog(@"after unlock");
}

@end


int main (int argc, const char * argv[]) {
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

    MyLock *lock = [[MyLock new] autorelease];
    @synchronized(lock) {
        NSLog(@"Hello World");
    }

    [pool drain];
}

ベストアンサー1

Objective-C 言語レベルの同期NSLockでは、 と同様に、ミューテックスが使用されます。意味的には若干の技術的な違いがありますが、基本的には、共通の (よりプリミティブな) エンティティ上に実装された 2 つの個別のインターフェイスと考えるのが正しいです。

特に、 ではNSLock明示的なロックが行われますが、 では、@synchronized同期に使用しているオブジェクトに関連付けられた暗黙的なロックが行われます。言語レベルのロックの利点は、コンパイラがそれを理解し、スコープの問題に対処できることですが、機械的には基本的に同じように動作します。

@synchronizedコンパイラの書き換えとして考えることができます:

- (NSString *)myString {
  @synchronized(self) {
    return [[myString retain] autorelease];
  }
}

次のように変換されます。

- (NSString *)myString {
  NSString *retval = nil;
  pthread_mutex_t *self_mutex = LOOK_UP_MUTEX(self);
  pthread_mutex_lock(self_mutex);
  retval = [[myString retain] autorelease];
  pthread_mutex_unlock(self_mutex);
  return retval;
}

実際の変換はより複雑で再帰ロックを使用するため、これは正確には正しくありませんが、要点は伝わるはずです。

おすすめ記事