2013-07-01 1 views
2

나는 누군가가 올바른 방향으로 나를 가리킬 수 있기를 바랄 뿐이라는 아주 간단한 질문을 가지고있다. 나는 글로벌 잠금에 대한 올바른 목표 C 접근법을 파악하려고하는 자바 개발자입니다. 여러 곳에서 인스턴스화 된 클래스가 있습니다. 각 인스턴스는 하나의 공통 파일을 읽고 씁니다. 따라서이 클래스의 모든 메서드 호출이 원자 적이어야합니다. Java에서는 다음과 같이 수행됩니다.객관적인 전체 수업을위한 잠금 C

static Object lock 

public void writeToFile(){ 
    synchronized(lock){ 
     //thread safe code goes here 
    } 
} 

정적 식별자는 모든 인스턴스에서 잠금 개체가 공유되므로 스레드 안전성이 높습니다. 불행히도 iOS에는 클래스 변수가 없기 때문에이 기능을 구현하는 가장 좋은 방법은 무엇인지 모르겠습니다.

+0

참고 : ... 더 많은 정보에 대한 스레드 프로그래밍 참조에 동기화를

스레드 프로그래밍 참조를 읽기 전 @synchronized (self.class)를 시도하고 아무 것도 불평하지 않았지만, 이것이 올바른 접근 방법이라고 100 % 확신하지 못했습니다. – akhalsa

+1

'@synchronized (self.class)'는 실제로 그 클래스의 모든 객체를 작동시키고 차단할 것입니다. 이 인스턴스를 잠그기 위해서라면,'@synchronized (self)'를 대신 사용하십시오. 비 차단 잠금이 필요한 경우 http://stackoverflow.com/questions/17396945/how-do-i-check-if-an-object-is-being-synchronized/17399427#17399427 –

답변

4

간단한 글로벌 잠금이 필요한 경우 NSLock을 확인하십시오.

예 :

static NSLock * myGlobalLock = [[NSLock alloc] init]; 

if ([myGlobalLock tryLock]) { 
    // do something 
    [myGlobalLock unlock]; 
} 
else { 
    // couldn't acquire lock 
} 

그러나, 그것은 커널 호출을 필요로하기 때문에 성능 저하를 초래할 것입니다. Grand Central Dispatch와 개인 큐를 사용하여 자원에 대한 액세스를 직렬화하려는 경우 커널 인터럽트없이 일정이 잡히게됩니다.

예 :

// alloc a dispatch queue for controlling access to your shared resource 
static dispatch_queue_t mySharedResourceQueue = nil; 
static dispatch_once_t onceToken; 
dispatch_once(&onceToken, ^{ 
    mySharedResourceQueue = dispatch_queue_create("com.myidentifier.MySharedResourceQueue", DISPATCH_QUEUE_SERIAL); // pick a unique identifier 
}); 
// don't forget to call dispatch_release() to clean up your queue when done with it! 

// to serialize access to your shared resource and block the current thread... 
dispatch_sync(mySharedResourceQueue, ^{ 
    // access my shared resource 
}); 

// or to access it asynchronously, w/o blocking the current thread... 
dispatch_async(mySharedResourceQueue, ^{ 
    // access my shared resource 
}); 

파견 큐가 매우 멋진 일이고, 당신은 아이폰 OS 개발에 받고 있다면 당신은 뛰어난 성능과 응용 프로그램을 만들기 위해 그것들을 사용하는 방법을 배워야한다.

NSLock 외에도 다양한 유형의 잠금 장치가 있습니다. https://developer.apple.com/library/ios/#documentation/Cocoa/Conceptual/Multithreading/Introduction/Introduction.html#//apple_ref/doc/uid/10000057i

NSLock 참조 : https://developer.apple.com/library/ios/#documentation/Cocoa/Reference/Foundation/Classes/NSLock_Class/Reference/Reference.html

그랜드 센트럴 파견 참조 : https://developer.apple.com/library/ios/#documentation/Performance/Reference/GCD_libdispatch_Ref/Reference/reference.html

+2

에 제공된 답변을 확인하십시오. 해당 대기열은 명시 적 DISPATCH _.._ SERIAL 옵션으로 작성되어야합니다. – bbum

+0

Apple의 docs에서 : "기본적으로 dispatch_queue_create()로 생성 된 큐는 이전에 대기열에서 제외 된 블록이 다음 블록을 대기열에 넣기 전에 완료 될 때까지 대기합니다.이 FIFO 완료 동작은 때때로 간단히"직렬 대기열 "로 설명됩니다." –

+1

그렇다고해서 코드에 명시 적이어서는 안된다는 의미는 아닙니다. 좀 더 명백한 동시성 코드 일수록, 앞으로 누군가를 유지하는 것이 더 쉬워집니다 (앞으로 6 개월 포함). 분명히 그것은 변경 될 수없는 기본 동작이지만, 미래의 유지 보수자가 그 동작을 찾도록 만드는 이유는 무엇입니까? – bbum