如何在@synchronized块中等待完成处理程序?

时间:2017-09-26 19:57:31

标签: ios objective-c multithreading semaphore ios-multithreading

我想在一个关键部分内同步调用一个完成处理程序(使用@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阻塞,在与调用者相同的线程上调用完成处理程序会导致死锁。是对的吗?如果是的话,还能实现这一目标吗?

谢谢!

1 个答案:

答案 0 :(得分: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
   }];

}