【发布时间】:2017-02-16 09:19:42
【问题描述】:
本网站上的一些问题涉及 C++11 中引入的多线程支持中缺少信号量对象。很多人建议implementing semaphores using mutexes or condition variables or a combination of both。
然而,这些方法都不允许在保证调用线程不被阻塞的同时增加和减少信号量,因为通常必须在读取信号量的值之前获取锁。例如,POSIX 信号量具有函数sem_post() 和sem_trywait(),它们都是非阻塞的。
是否可以仅使用 C++11 多线程支持来实现非阻塞信号量?或者我是否必须为此使用依赖于操作系统的库?如果是这样,为什么 C++11 版本不包含信号量对象?
similar question 已 3 年未得到答复。 (注意:我相信我要问的问题要广泛得多,除了生产者/消费者之外,非阻塞信号量对象肯定还有其他用途。如果尽管如此,有人认为我的问题是重复的,那么请告诉我如何我可以重新关注旧问题,因为这仍然是一个悬而未决的问题。)
【问题讨论】:
-
你为什么关心信号量是否阻塞?如果您因为认为非阻塞信号量比阻塞信号量表现更好而关心,那么这是一个 XY 问题。您真正想要的是具有您认为非阻塞信号量具有的性能水平的信号量,而您实际上并不关心它是如何实现的。
-
我认为实现信号量没有问题。使用 C++11 atomics 和 mutextes 应该是可能的。我在这里找到了一个实现:stackoverflow.com/questions/4792449/…
-
@SingerOfTheFall 你对锁有一个常见的误解。锁不是“浪费时间等待”,而是允许竞争线程被取消调度,以便非竞争线程可以运行。
-
@SingerOfTheFall 不,一点也不。当其他线程使用 CPU 时,线程不是“浪费时间”。它被阻止并允许系统做有用的工作。最糟糕的情况是当您使用无锁算法时,它允许两个竞争线程同时运行,当它们争夺缓存线时,整个系统都会慢下来。线程并不处于战争状态,每个线程都只为自己工作。当竞争线程不并发运行并且争用最小化时,它们都会受益,因此它们可以快速完成并允许其他任务也可以全速完成。
-
当使用
sem_post时,如果等待,线程会被唤醒。这意味着它必须处于阻塞状态。要求非阻塞信号量是……不寻常的。如果你跳过sem_wait,只使用sem_trywait,那么使用原子非常容易。
标签: c++ multithreading c++11