0

(@synchronizedブロックを使用して)クリティカルセクション内で完了ハンドラを同期して呼び出す必要があります。私はセマフォを使って補完ハンドラを待つつもりですが、セマフォ信号は決して呼び出されません。@synchronizedブロック内で補完ハンドラを待つ方法は?

NSNumber *lock = 0; 
@synchronized(lock) { 
    // critical section code begins 
    dispatch_semaphore_t sema = dispatch_semaphore_create(0); 
    [self someMethodWithCompletionHandler:^(BOOL result) { 
     // execute completion handler 
     dispatch_semaphore_signal(sema); 
    }]; 
    // wait for completion block to finish 
    dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER); 
    // critical section code ends 
} 

私は信じて、原因完了ハンドラがデッドロックになり、呼び出し側と同じスレッドで呼び出される@synchronizedブロックに:ここで

は私がやっているものです。そうですか?もしそうなら、それ以外はどのように達成できますか?

ありがとうございます!

+0

クラスの初期化時にシリアルキューを作成する必要があります。あなたは 'someMethodWithCompletionHandler'がその作業を行い、完了待ちハンドラを別の待ち行列に、あなたが 'wait'でブロックしたものとディスパッチするようにする必要があります。あなたがメインキューを待っているなら、それは非常に悪いです。同期ブロックを追加するだけで、2つ目のホールド・アンド・ウェイトデッドロックの可能性があるため、複雑になります。 – Paulw11

+0

@syncrhonizedブロックを使うのではなく、プライベートなシリアルディスパッチキューにクリティカルセクション全体を非同期でディスパッチし、別のユーティリティキューまたはメインキューに非同期で 'someMethodWithCompletionHandler'をディスパッチします。その後、セマフォはプライベートキューを安全にブロックできます。 – Paulw11

+0

しかし、クリティカルセクションコードを同期化したいと思います。クリティカルセクション全体を非同期的に別のシリアルスレッドにディスパッチして非同期にしませんか?私は、クリティカルセクションの後に実行されるクリティカルセクションの後にコードを持っています。 –

答えて

0

私は@synchronizedを避け、シリアルディスパッチキューを使用してクリティカルセクションで作業をシリアル化します。非同期操作が完了するまで、セマフォを使用してシリアルディスパッチキューをブロックすることはできます。

シリアルディスパッチキューは、一度に1つのコードブロックしかクリティカルセクションに入ることができず、メインキューをブロックする危険性がないことを保証します。

あなたはそれを試してみて、非同期物事を同期させるために、一般的に悪い考えです

@property (strong,nonatomic) dispatch_queue_t serialQueue; 

- (id)init { 
    if (self = [super init]) { 
     self.serialQueue = dispatch_queue_create("com.example.CriticalTaskQueue", NULL); 
    } 
    return self; 
} 

- submitSomeCriticalWork() { 

    dispatch_async(self.serialQueue, ^{ 
     dispatch_semaphore_t sema = dispatch_semaphore_create(0); 
     [self someMethodWithCompletionHandler:^(BOOL result) { 
     // execute completion handler 
      dispatch_semaphore_signal(sema); 
     }]; 
    // wait for completion block to finish 
    dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER); 
    // critical section code ends 
    }]; 

} 
関連する問題