Как ждать обработчик завершения внутри блока @synchronized?

Я хочу вызвать обработчик завершения синхронно внутри критической секции (используя @synchronized block). Я пытаюсь дождаться завершения обработчика с помощью семафора, но сигнал семафора никогда не вызывается.

Вот что я делаю:

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 обработчик завершения вызывается в том же потоке, что и вызывающая программа, что приводит к взаимоблокировке. Это правильно? Если да, как еще этого можно достичь?

Спасибо!

1 ответ

Я бы избежал @synchronized и использовать очередь последовательной отправки для сериализации работы в критическом разделе. Вы все еще можете использовать семафор, чтобы заблокировать очередь последовательной отправки, пока асинхронная операция не будет завершена.

Очередь последовательной отправки гарантирует, что только один блок кода может войти в критическую секцию за раз, и нет риска блокировать основную очередь.

Вам нужно будет создать последовательную очередь во время инициализации вашего класса

@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
   }];

}
Другие вопросы по тегам