2012-02-27 2 views
6
static pthread_mutex_t gLock; //global 

pthread_mutex_init(&gLock,NULL); //in init 

pthread_mutex_lock(&gLock); 
for(int i=0;i<[message count];i++) 
CFSetAddValue(mSet, [message objectAtIndex:i]); 
pthread_mutex_unlock(&gLock); 

내 코코아 응용 프로그램이 pthread_mutex_t를 사용하여 응답하지 않습니다.pthread_mutex_t VS @ 동기화 된 블록?

@synchronized(mSet) 
{ 
for(int i=0;i<[message count];i++) 
    CFSetAddValue(mSet, [message objectAtIndex:i]); 
} 

내 응용 프로그램이 동기화 된 블록으로 잘 작동합니다.

왜?

답변

8

전역 잠금 (모든 인스턴스에 대해 하나의 잠금)을 객체 레벨 순환 잠금 (인스턴스 당 하나의 잠금, 동일한 스레드에서 여러 번 획득 할 수 있음)과 비교합니다. 이들은 일반적으로 교환 할 수 없습니다 - 그들은 서로 매우 다르게 작동하고 보호합니다.

좋은 소식은 @synchronized과 동일한 보호 수준을 달성하기 위해 각 인스턴스에 고유 한 재귀 잠금으로 pthread_mutex_t을 사용할 수 있다는 것입니다. pthread_mutex_t을 사용하면 잠금 획득을 훨씬 빠르게 수행 할 수 있습니다.

pthread 뮤텍스를 사용하여 @synchronized과 동일한 효과를 얻으려면 pthread_mutex_t gLock을 인스턴스 변수로 선언 한 다음 -init의 재귀 뮤텍스로 초기화하십시오. 마지막으로 -dealloc에있는 뮤텍스를 파괴하십시오.

하위 클래스와 기본 클래스는 개체 계층 구조를 통해 올바른 작업을 수행하기 위해 @synchronized의 의미에 의존하는 경우이 잠금에 대한 액세스가 필요할 수 있습니다.

@synchronized은 반복적 인 pthread 뮤텍스와 비교하여 느리다.

+1

.h 파일 \t에서 pthread_mutexattr_t attr; \t pthread_mutex_t mutex; (초기화시) \t \t pthread_mutexattr_settype (& attr, PTHREAD_MUTEX_RECURSIVE); \t \t pthread_mutex_init (뮤텍스, 할당 해제에 &attr); 가 pthread_mutex_destroy (뮤텍스) 내 기능 에 pthread_mutex_lock에 (뮤텍스) \t \t \t \t CFSetRemoveAllValues ​​(요소인지) \t \t \t pthread_mutex_unlock을 (뮤텍스) 은 이게 뭐야? –

+1

@ParagBafna a) 뮤텍스 attr은 '정적'일 수 있으며 생성 한 모든 뮤텍스에 사용할 수 있습니다. 또는 정적이 아니며'-init'에서만 사용됩니다. b) 뮤텍스 attr은 ivar 일 필요는 없습니다. c) 결과 코드 d) 경우에 따라'pthread_mutex_trylock '을 선호 할 수도 있습니다. e) 이니셜 라이저를 사용하여 구조체를 초기화해야합니다. 그 외의, 잘 보인다! 빠른 잠금 = 준비) – justin

+0

결과 코드는 주로 잠금 및 스레드 오류를 감지하는 데 유용합니다. (들은 pthread_mutex_t *) PTHREAD_MUTEX_RECURSIVE_LOCK -. – justin

0

저스틴 말이 맞습니다. 그러나 예외 처리 인 또 다른 세부 사항이 있습니다. https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/Multithreading/ThreadSafety/ThreadSafety.html에서이 팁 제공 : 예방 조치로

을의 @synchronized 블록은 암시 적으로 보호 된 코드에 대한 예외 처리기를 추가합니다. 이 처리기는 예외가 발생하는 경우 자동으로 뮤텍스를 해제합니다. 즉, @synchronized 지시어를 사용하려면 코드에서 Objective-C 예외 처리를 활성화해야합니다. 암시 적 예외 핸들러로 인한 추가 오버 헤드를 원하지 않으면 잠금 클래스 사용을 고려해야합니다.

[message count]은 잠금 해제 코드를 뛰어 넘을 수있는 예외를 발생시킬 수 있습니다.

+0

... 복구 할 수 있다면. 대부분의 코코아 예외는 복구 할 수 없습니다 (적어도 이후에 예측 가능한 실행을 원할 경우). 복구 가능한 예외에 대한 일반적인 경우는 C++ (예측 가능한 복구)입니다. – justin

관련 문제