它们都使用计数器,并使用锁来保护计数器的增量和减减量,当计数器小于零时,线程等待,在我看来,除了它们的API不同之外,它们都是一样的。
0vvn1miw1#
苹果在他们的文档中写了关于DispatchSemaphoresignal()方法的内容:此函数唤醒当前在dispatch_semaphore_wait(::)中等待的线程。与DispatchSemaphore不同,NSCondition有两种不同的方法:1)broadcast():发出条件信号,唤醒等待它的所有线程。2)signal()发出条件信号,唤醒一个等待它的线程。
DispatchSemaphore
signal()
NSCondition
broadcast()
bsxbgnwa2#
我认为调度信号量是一个更高级别的概念,如果不需要,它不一定涉及锁定,而NSCondition是pthread条件的 Package 器,因此总是涉及线程级别的锁定。调度信号量与调度队列协同工作,并不是每个调度队列都必须在不同的线程上(因为使用线程池)。必须以经典方式使用NSCondition,包括以下步骤:在等待侧:
在信令/广播端:
演示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
分派信号量的用法要简单得多,因为你不需要锁定它,你可以直接把它用作 predicate 。它只是充当一个计数器,每个等待减少它的值,每个信号增加它的值。它的使用可能会被限制在需要额外锁定的更复杂的 predicate 中。来自文档:分派信号量是传统计数信号量的有效实现。分派信号量仅在调用线程需要阻塞时才向下调用内核。如果调用信号量不需要阻塞,则不进行内核调用。
iaqfqrcu3#
使用DispatchSemaphore时,必须注意平衡每个wait()与signal()。NSCondition除了允许更灵活的 predicate 类型外,在等待方面也更灵活。如果 predicate 已经为真,则可以满足无限数量的读取器。如果 predicate 尚未为真,则单个broadcast()可以唤醒多个等待器。
wait()
3条答案
按热度按时间0vvn1miw1#
苹果在他们的文档中写了关于
DispatchSemaphore
signal()
方法的内容:此函数唤醒当前在dispatch_semaphore_wait(::)中等待的线程。
与
DispatchSemaphore
不同,NSCondition
有两种不同的方法:1)
broadcast()
:发出条件信号,唤醒等待它的所有线程。
2)
signal()
发出条件信号,唤醒一个等待它的线程。
bsxbgnwa2#
我认为调度信号量是一个更高级别的概念,如果不需要,它不一定涉及锁定,而NSCondition是pthread条件的 Package 器,因此总是涉及线程级别的锁定。
调度信号量与调度队列协同工作,并不是每个调度队列都必须在不同的线程上(因为使用线程池)。
必须以经典方式使用NSCondition,包括以下步骤:
在等待侧:
在信令/广播端:
演示NSCondition用法的示例类别(目标C):
分派信号量的用法要简单得多,因为你不需要锁定它,你可以直接把它用作 predicate 。它只是充当一个计数器,每个等待减少它的值,每个信号增加它的值。它的使用可能会被限制在需要额外锁定的更复杂的 predicate 中。
来自文档:
分派信号量是传统计数信号量的有效实现。分派信号量仅在调用线程需要阻塞时才向下调用内核。如果调用信号量不需要阻塞,则不进行内核调用。
iaqfqrcu3#
使用
DispatchSemaphore
时,必须注意平衡每个wait()
与signal()
。NSCondition
除了允许更灵活的 predicate 类型外,在等待方面也更灵活。如果 predicate 已经为真,则可以满足无限数量的读取器。如果 predicate 尚未为真,则单个broadcast()
可以唤醒多个等待器。