标准 C++atomic_flag 在调用 notification_one() 时从 wait() 唤醒线程有多“公平”

问题描述 投票:0回答:3

当调用notify_one()时,是否有关于在atomic_flag上调用wait()的线程被唤醒的顺序的公平性信息。它们是否按照进入 wait() 的确切顺序被唤醒,可以说是 FIFO 吗?

原子标志变量似乎返回“始终无锁”。我知道它们在任何实现中都保证是无锁的,但我不确定如果使用 wait() 它们是否仍然是无锁的,因此某种机制必须决定服务员的唤醒。其他一些同步方法可以保证公平性,但是以幕后内存分配为代价的。

有谁知道这是如何与atomic_flags一起使用的。我将所有同步器更改为使用原子标志,并且它们工作得非常快。然而我忽略了公平性。

谢谢你。

c++ multithreading concurrency atomic lock-free
3个回答
1
投票

标准不提供任何保证,这将取决于标准库的实现。

甚至不能保证只有一个线程被解锁。任何数量的合格线程(但如果至少有一个合格的话,则至少有一个)可以被解除阻塞。只需将

notify_one
转发到
notify_all
的实现就符合要求。


0
投票

C++ 标准在这里没有提出任何要求 - 每个实现都可以自由唤醒它认为最合适的线程。

如果这对您很重要,您可能需要在适用于您的平台的编译器之间进行比较。


0
投票

总结一下几个答案,答案是:

  • 标准 C++ 规范没有任何与atomic_flags 公平性相关的指南,并且可能扩展到所有其他原子类型。

  • 每个实现都可以根据需要唤醒等待线程。

  • 使用notify_all()而不是notify_one()将使所有线程有几乎平等的机会竞争atomic_flag并将其进一步留给调度程序。

  • 抢占式线程调度程序引导乐团确定哪个线程获得第一个机会。我由此得出结论,使用notify_all(),线程饥饿可能变得不可能,或者至少问题较少,因为调度程序会给每个线程机会。

  • 多核无论如何都不能保证同一个线程始终完全在同一个核心上执行,因此公平性不会在尝试更好地在多个核心上分散负载时带来任何影响。

谢谢大家。现在感觉很好,因为公平问题比我最初想象/担心的要小。

© www.soinside.com 2019 - 2024. All rights reserved.