2011-12-27 4 views
1

각각 다른 스레드에 2 개의 메소드가 있습니다.Objective C에서 2 개의 스레드를 동기화하십시오.

Method1은 중요한 섹션에 있지만 Method2는 대기해야합니다. Method2가 지속적으로 실행되므로 Method1이 중요한 섹션에서 작동하는 경우에만 기다려야합니다. 그렇지 않으면 작업을 계속하십시오.

어떻게하면됩니까?

의사 코드 :

Method1 
{ 
     Announce the entrence to critical-section 
     ......Do some stuff......... 
     Announce the leaving of critical-section 
} 


Method2 
{ 
     Method1 is in its critical-section? - WAIT TILL IT DONE 
     ......Do some stuff........... 
} 
+1

에 StackOverflow는 단지 하나 개의 문자 DIFF하지만 그것은 매우 중요한 하나 개의 문자 DIFF 때문에 내가이를 편집 할 수 없습니다 : 당신이 방법 항목이 중요 섹션에 "말할 방법 2의 내부 의사 코드를 변경해야 "(Method2가 중요 섹션에 없음) –

답변

1

두 스레드 간의 동작을 안정적으로 제어하려면 조건 변수를 사용해야합니다. 기술적으로 변수를 공유하는 것만으로도 다른 답변을 제안 할 수 있지만 다른 시나리오에서는 빠르게 분해됩니다.

BOOL isMethod1Busy = NO; 
NSCondition *method1Condition = [[NSCondition alloc] init] 

- (void)method1 
{ 
    [method1Condition lock]; 
    isMethod1Busy = YES; 

    // do work 

    isMethod1Busy = NO; 
    [method1Condition signal]; 
    [method1Condition unlock]; 
} 

- (void)method2 
{ 
    [method1Condition lock]; 
    while (isMethod1Busy) { 
     [method1Condition wait]; 
    } 

    // do stuff while method1 is not working 

    [method1Condition unlock]; 
} 
+0

그냥 내 자신의 이해를 위해, 다른 어떤 시나리오에서 단순한 부울이 분리됩니까? –

+0

조건부 영역을 종료하기 전에 솔루션에 'isMethod1Busy = NO'가 누락되지 않았습니까? @pcperini : 변수 값이 변경 될 때까지 기다릴 수 없기 때문에 간단한 부울이 작동하지 않습니다. 주기적으로 "busy wait"또는 "poll"을 점검해야합니다. 일반적으로 적절한 대기를 위해 훨씬 빈약 한 해결책입니다. – CRD

+0

@CRD 좋습니다, NSConditions를 사용하는 좋은 이유로 폴링 대 경고를 구입합니다. 그러나 궁극적으로 아무 것도 깨지지 않을 것이며 가능한 효율성이 부족합니다. –

0

게다가 구조적으로, 당신은 아마 당신의 소프트웨어를 설계해야하는 이벤트 기반 대신 당신이 여기에서 무엇을, 나는이 가정하는 것 당신이 할 NSNotificationCenter를 사용할 수있을 것을 지적 Method1의 "발표"부분.

-(void)method2 { 

    if (self.skipProcessing) 
     return; 

    //normal code here.. 
} 
0

당신은 동기화 (논리적으로 두 방법보다 어딘가에 할당) 일부 공유 변수를 사용한다 :

당신이 할 수있는 또 다른 것은 고려 위의주의 사항,이 처리를 건너 뛰어야 말 인스턴스에 BOOL을 설정 방법.

여기서는 스레딩을 처리하기 위해 NSThread과 같은 것을 사용하고 있다고 가정합니다.

- (void)Method1: 
{ 
    self.SYNC_LOCK = YES; 
    // do some stuff 
    self.SYNC_LOCK = NO; 
} 

- (void)Method2: 
{ 
    if (self.SYNC_LOCK) {return;} 
    // do some stuff 
} 

간단한 스레딩 라이브러리를 찾고있는 경우 Grand Central Dispatch를 살펴 봐야합니다. 나는 이러한 종류의 것들을 멋지게 감싸는 라이브러리 (GCD - GitHub)를 가지고있다.

- (void)Method1 
{ 
    [GCD doInBackground: ^{ 
     self.SYNC_LOCK = YES; 
     // do some stuff 
     self.SYNC_LOCK = NO; 
    }]; 
} 

- (void)Method2 
{ 
    void (^stuff_block)(void) = ^{ 
     while (!self.SYNC_LOCK) {sleep(SOME_WAIT_TIME);} 
     //do some stuff 
    }; 
    [GCD doInBackground: stuff_block every: FEW_SECONDS]; 
} 
+0

첫 번째 제안이 원래 문제에 대한 해결책이라고 생각하지 않습니다. 기다리지 않고 리턴합니다. 두 번째 방법은 기다리지 않고 투표하는 좋은 방법이 아닙니다. – CRD

관련 문제