我想在一个关键部分内同步调用一个完成处理程序(使用@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 :(得分: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
}];
}