我最近一直在使用NSCondition,我真的不明白锁定和解锁部分。
例如,
NSCondition lock = [NSCondition new];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
//Do stuff
[lock signal];
};
[lock wait];
//Do rest
这很好用。它与此有什么不同..
NSCondition lock = [[NSCondition alloc] init];
[lock lock];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
//Do stuff
[lock signal];
[lock unlock];
};
[lock wait];
//Do rest
答案 0 :(得分:3)
在等待之前,您必须对条件变量进行锁定。 等待释放锁定,然后保证阻止,直到它被发出信号并重新锁定。请注意,如果多个线程正在等待,则只有一个线程会收到信号通知,其他线程将继续等待更多信号。或者,如果谓词在执行后仍然为真,则可以将信号广播到所有线程。
锁是一个互斥锁(互斥锁),这意味着任何时候只有一个线程可以持有锁。除了使用它来保护你正在使用条件变量的任何东西,它还保护条件变量的内部工作。如果您试图在没有锁定的情况下使用它,则在多个线程上检查/设置条件时会出现竞争条件。
为了正确使用条件变量, 的示例都不正确。重点是要保护谓词的状态。以下示例基于the documentation的伪代码。
NSCondition condvar = [NSCondition new];
__block BOOL workRequired = NO;
// something somewhere else does this at some point ^{
[condvar lock];
workRequired = YES;
[condvar signal];
[condvar unlock];
};
[condvar lock];
while (!workRequired) {
[condvar wait];
}
// Do the work
workRequired = NO;
[condvar unlock];
在您的示例中,除了“块完成”之外,您没有任何条件。在这种情况下,您应该只使用dispatch_sync。
dispatch_sync(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// Do stuff
};
// Do rest
如果由于某种原因你不知道你是否已经在该队列上运行,那么semaphore就足够了。
dispatch_semaphore_t semaphore = dispatch_semaphore_create(0L);
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// Do stuff
dispatch_semaphore_signal(semaphore);
};
dispatch_semaphore_wait(semaphore);
// Do rest