2011-12-27 12 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のは、それが唯一の文字の差分だが、それは非常に重要な1つの文字の差分なので、私はこれを編集できません:あなたは方法1は、そのクリティカルセクションにある」と言って方法2の内部で擬似コードを変更する必要があります"(Method2はクリティカルセクションではありません) –

答えて

1

2つのスレッド間の動作を確実に制御するには、条件変数を使用する必要があります。技術的には、変数を共有するだけで、他の答えが示唆していることを行うことができますが、他のシナリオではすぐに解消されます。

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:変数の値が変わるのを待つことができないので、単純なブール値は機能しません。定期的に "ビジー待機"または "ポーリング"をチェックする必要があります。 – CRD

+0

@CRD OK、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

最初の提案は元の問題の解決策ではないと思います。 2つ目は、待機するのではなく投票するため、おそらく良い解決策ではありません。 – CRD

関連する問題