【问题标题】:std::condition_variable notify_all not waking up all threads at the same timestd::condition_variable notify_all 不会同时唤醒所有线程
【发布时间】:2018-01-12 06:14:39
【问题描述】:

我想知道的是 std::condition_variable notify_all 如何通知所有线程唤醒。

情况是我有一个主线程,一个渲染线程,每个线程都有自己的线程池来完成它需要的任何工作。例如,如果我有 6 个逻辑核心,则每个线程池将有 6 个工作线程。这些线程是使用 notify_all 唤醒的。每个线程池都有自己的条件变量/互斥体组合,并且是完全独立的,因此它们不会相互冲突。

我遇到的问题是,有时,当渲染线程调用 notify_all 来唤醒工作线程时,有些会立即唤醒,有些会需要很长时间,大约为几毫秒。

我还注意到,这主要发生在这些线程被唤醒而主线程工作人员忙于自己的工作时。因此,在每个逻辑核心已经有一个线程在工作的重负载时,尝试唤醒这些其他线程会表现出这种行为。所以在等待 condition_variable 的 6 个线程中,可能有 4 个会被唤醒,另外两个直到负载下降时才会被唤醒。

我的问题是,这是预期的行为,还是我应该寻找代码中的错误?请注意,线程总是唤醒,并且在空载或轻负载下,它们通常在大约同一时间唤醒。我的线程池设置也没有死锁或任何其他问题。那么,我是否只是看到了 condition_variable 的正确行为,其中一些线程可以快速唤醒,而另一些线​​程可以在 4 或 5 毫秒后唤醒?如何减轻这种行为?谁能建议一种替代方法来唤醒我的工作线程可能效果最好?

提前致谢。

【问题讨论】:

    标签: windows multithreading c++11 threadpool condition-variable


    【解决方案1】:

    在他们被安排之前,他们无法被唤醒。如果其他线程正在运行,它们将首先完成它们的时间片。

    这还能如何工作?

    【讨论】:

    • 好吧,也许我一直在理解调度程序如何错误地处理所有这些线程。我认为它可以阻止一些人给其他人时间,试图平衡负载?你是说一旦一个线程开始运行,它就无法停止,直到它产生或发生一些同步?
    • @Owens 一旦操作系统启动一个线程,它就会运行它的时间片。然后它会被中断,操作系统会重新调度。
    • 对,这是我的总体印象。我只是认为时间片会更短。我看到的是这些线程中的一些等待 4 或 5 毫秒,基本上直到其他正在运行的线程完全进入睡眠状态等待它们的同步。而且,请注意,当这些线程正在执行它们的工作时,在每个工作之后都会有一个让步,特别是为了让其他线程有机会运行。所以我在这里感到困惑,因为我至少期望其中一个收益允许 condition_variable 唤醒这些线程。
    • msdn.microsoft.com/en-us/library/windows/desktop/… 由于切片是20ms 5ms实际上是相当不错的。
    • 出于某种原因,我在考虑 Windows。其他操作系统做不同的事情。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-12-04
    • 1970-01-01
    • 2022-06-16
    • 2021-06-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多