【发布时间】:2017-09-26 19:57:31
【问题描述】:
我想在关键部分内同步调用完成处理程序(使用 @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 块,完成处理程序在与调用者相同的线程上被调用,这会导致死锁。那正确吗?如果是,还有什么方法可以实现?
谢谢!
【问题讨论】:
-
尝试使异步事物同步通常是个坏主意。您需要确保
someMethodWithCompletionHandler既能完成工作,又会将完成处理程序分派到不同队列中,以与您使用“等待”阻塞的队列进行处理。如果您在主队列上等待,那将非常糟糕。添加同步块只会使其变得更加复杂,因为您现在有第二个潜在的保持等待死锁触发器。 -
我不会使用@syncrhonized 块,而是将整个临界区异步调度到私有串行调度队列上,并将
someMethodWithCompletionHandler异步调度到另一个实用程序队列或主队列上。然后你的信号量可以安全地阻塞你的私有队列。 -
但是我希望临界区代码是同步的。将整个临界区异步调度到另一个串行线程会使其异步吗?我在关键部分之后有代码,应该在关键部分完成后执行。
-
@Paulw11 我尝试使用 dispatch_sync 但它在主线程中执行!有什么想法吗?
-
不要使用调度同步。接受它应该是异步的事实。使用 dispatch group 和 dispatch group notify 来执行临界区之后的代码。调度同步将在你调度到的任何队列上执行代码,但它仍然会阻塞当前队列等待该调度完成,如果当前队列是主队列,这很糟糕。即使您分派到另一个队列,如果该线程可用,代码也可能在主线程上执行。主队列总是使用主线程。其他队列可能使用主线程
标签: ios objective-c multithreading semaphore ios-multithreading