1

我想在关键部分内同步调用完成处理程序(使用 @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 块,完成处理程序在与调用者相同的线程上被调用,这会导致死锁。那正确吗?如果是,还有什么方法可以实现?

谢谢!

4

1 回答 1

0

我会避免@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
   }];

}
于 2017-09-28T21:04:15.927 回答