source

Objective-C에서 @synchronized 잠금/잠금 해제 방법은 무엇입니까?

itover 2023. 4. 22. 09:20
반응형

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];
}

Objective-C 언어 레벨 동기화에서는 다음과 같이 뮤텍스를 사용합니다.NSLock의미적으로는 작은 기술적 차이가 있지만 기본적으로는 공통(더 원시적인) 엔티티 위에 구현된 두 개의 개별 인터페이스로 간주하는 것이 옳습니다.

특히,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;
}

실제 변환은 더 복잡하고 재귀 잠금을 사용하기 때문에 정확하지는 않지만 요점을 전달해야 합니다.

목표-C에서는@synchronized블록 핸들 잠금 및 잠금 해제(가능한 한 예외)를 자동으로 수행합니다.런타임은 기본적으로 동기화하는 개체와 관련된 NSRecursiveLock을 생성합니다. Apple 문서에서는 이에 대해 자세히 설명합니다.따라서 NSLock 서브클래스에서 로그 메시지가 표시되지 않습니다.동기화하는 오브젝트는 NSLock뿐만 아니라 모든 것이 될 수 있습니다.

기본적으로는@synchronized (...)코드를 합리화하는 편리한 구성입니다.대부분의 단순화된 추상화처럼 오버헤드(숨겨진 비용이라고 생각됨)가 관련되며, 이를 인식하는 것은 좋지만 이러한 구조를 사용할 때 원시 성능이 최고의 목표는 아닐 수 있습니다.

정말로.

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

다음과 같이 직접 변환:

// needs #import <objc/objc-sync.h>
{
  objc_sync_enter(self)
    id retVal = [[myString retain] autorelease];
  objc_sync_exit(self);
  return retVal;
}

이 API는 iOS 2.0 이후 사용 가능하며 다음을 사용하여 Import되었습니다.

#import <objc/objc-sync.h>

Apple의 @synchronized 실장은 오픈 소스이며, 여기서 확인할 수 있습니다.Mike Ash는 이 주제에 대해 두 개의 매우 흥미로운 글을 썼다.

즉, 오브젝트 포인터(메모리 주소를 키로 사용)를 매핑하는 테이블이 있습니다.pthread_mutex_t을 사용하다

세마포어를 모든 물체와 연관시켜 사용합니다.

언급URL : https://stackoverflow.com/questions/1215330/how-does-synchronized-lock-unlock-in-objective-c

반응형