Как ждать обработчик завершения внутри блока @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
}];
}