除了API之外,iOS中的NSCondition和dispatch_信号量还有什么区别?

sr4lhrrt  于 2023-03-05  发布在  iOS
关注(0)|答案(3)|浏览(130)

它们都使用计数器,并使用锁来保护计数器的增量和减减量,当计数器小于零时,线程等待,在我看来,除了它们的API不同之外,它们都是一样的。

0vvn1miw

0vvn1miw1#

苹果在他们的文档中写了关于DispatchSemaphoresignal()方法的内容:
此函数唤醒当前在dispatch_semaphore_wait(:)中等待的线程。
DispatchSemaphore不同,NSCondition有两种不同的方法:
1)broadcast()
发出条件信号,唤醒等待它的所有线程。
2)signal()
发出条件信号,唤醒一个等待它的线程。

bsxbgnwa

bsxbgnwa2#

我认为调度信号量是一个更高级别的概念,如果不需要,它不一定涉及锁定,而NSCondition是pthread条件的 Package 器,因此总是涉及线程级别的锁定。
调度信号量与调度队列协同工作,并不是每个调度队列都必须在不同的线程上(因为使用线程池)。
必须以经典方式使用NSCondition,包括以下步骤:
在等待侧:

  • 锁定条件
  • 在while循环中,检查 predicate 并等待条件
  • 解锁条件

在信令/广播端:

  • 锁定条件
  • 更改会更改 predicate 的基础值
  • 用信号通知/广播该状况
  • 解锁条件

演示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 中。
来自文档:
分派信号量是传统计数信号量的有效实现。分派信号量仅在调用线程需要阻塞时才向下调用内核。如果调用信号量不需要阻塞,则不进行内核调用。

iaqfqrcu

iaqfqrcu3#

使用DispatchSemaphore时,必须注意平衡每个wait()signal()NSCondition除了允许更灵活的 predicate 类型外,在等待方面也更灵活。如果 predicate 已经为真,则可以满足无限数量的读取器。如果 predicate 尚未为真,则单个broadcast()可以唤醒多个等待器。

相关问题