它们都使用计数器,并使用锁来保护计数器的递增和递减,当计数器小于零时,线程等待。在我看来,除了它们的 api 之外,它们是相同的。
2 回答
我认为调度信号量是一个更高级别的概念,如果不需要,它不一定涉及锁定,而 NSCondition 是 pthread 条件的包装器,因此总是涉及线程级别的锁定。
调度信号量与调度队列一起工作,并不是每个调度队列都必须在不同的线程上(因为使用了线程池)。
NSCondition 必须以经典方式使用,包括以下步骤:
在等待方面:
- 锁定条件
- 在while循环中,检查谓词并等待条件
- 解锁条件
在信令/广播方面:
- 锁定条件
- 更改将更改谓词的基础值
- 信号/广播条件
- 解锁条件
演示 NSCondition 用法的示例类别(目标 C):
@implementation NSCondition(Extension)
- (void)signalPredicateModification:(void (NS_NOESCAPE ^)(void))predicateModification {
@try {
[self lock];
predicateModification();
[self signal];
} @finally {
[self unlock];
}
}
- (void)waitForPredicate:(BOOL (NS_NOESCAPE ^)(void))predicate {
@try {
BOOL predicateResult = NO;
[self lock];
while (!(predicateResult = predicate())) {
[self wait];
}
} @finally {
[self unlock];
}
}
@end
调度信号量的使用要简单得多,因为您不需要锁定它,您可以直接将其用作谓词。它只是充当一个计数器,每次等待都会减少它的值,而每个信号都会增加它。对于需要额外锁的更复杂的谓词,它的使用可能会受到限制。
从文档中:
调度信号量是传统计数信号量的有效实现。仅当调用线程需要被阻塞时,调度信号量才会向下调用内核。如果调用信号量不需要阻塞,则不进行内核调用。
Apple 在他们的文档中写道DispatchSemaphore
signal()
:
此函数唤醒当前在 dispatch_semaphore_wait( : :)中等待的线程。
与, 不同DispatchSemaphore
,NSCondition
有 2 种不同的方法:
1)broadcast()
:
发出条件信号,唤醒所有等待它的线程。
2)signal()
发出条件信号,唤醒一个等待它的线程。