【问题标题】:Thread sleep VS wait condition线程睡眠 VS 等待条件
【发布时间】:2017-07-02 12:48:18
【问题描述】:

编辑:

这里的重点是了解实现等待循环的更有效的解决方案,该循环在每次迭代时轮询一个条件。高效,我的意思是“高效的 CPU 调度”。

我知道我的代码中使用的等待条件不是使用“wakeOne”/“wakeAll”指令的“真正等待条件”,但我想知道使用假等待条件是否比 CPU 更有效睡一觉。

原帖:

这里有 2 个代码 sn-ps,它们做同样的事情:等到有事情发生。此代码用于工作线程池。因此,当一个线程等待时,其他线程(或其他一些线程)应该处理它们的指令。

第一个使用“睡眠”,第二个使用“等待条件”。 它们是用 Qt 编写的,但可以轻松转换为 C++11、Boost 或任何线程库。

两者都运作良好,但有任何性能差异吗?我记得我在某处读过:

“睡眠”会导致主动等待,因此 CPU 会花时间等待。

“等待条件”使 CPU 等待一个事件,因此 CPU 在等待期间切换到另一个线程执行

我记得很清楚吗?真的吗 ?使用等待条件并行执行多个线程更有效?

“睡眠”版本:

while (someCondition == false)
{
    sleep(100);
}

// Do some work

“WaitCondition”版本:

QMutex mutex(QMutex::NonRecursive);
QWaitCondition waitCondition;

while (someCondition == false)
{
    QMutexLocker locker(&mutex);
    waitCondition.wait(&mutex, 100);
}

// Do some work

【问题讨论】:

  • ""sleep" 导致主动等待,因此 CPU 花时间等待。" False.
  • 你能指出一些关于睡眠/等待条件的文档来确认吗?
  • @Jarod42 我认为 OP 意味着他的“睡眠”解决方案在轮询条件时会做一些(轻度)忙等待......
  • 我认为效率非常依赖于系统。我相信,一旦我看到条件变量的 wait() 函数的实现之一,只需睡眠 20 毫秒并检查条件

标签: c++ multithreading async-await


【解决方案1】:

已编辑:

两个版本是相同的,因为调用线程都是“阻塞”或“挂起”(即从调度程序的“可运行”列表中删除它)。

http://pubs.opengroup.org/onlinepubs/9699919799/functions/sleep.htmlhttp://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_cond_timedwait.html

在睡眠和等待 CV 期间,线程不使用 CPU 的任何时钟周期。

原文:

差异很大。第一个示例(带睡眠)将在 0-100 毫秒内对事件做出反应。另一个 - 带有条件变量 - 将“立即”做出反应。那是因为 sleep 就是这样做的——在你请求的确切时间内睡眠(注意——让我们假设你的系统不使用 POSIX 风格的信号)。另一方面,只要您请求,条件变量就会等待除非它收到条件可能已更改的通知。

【讨论】:

  • 在本例中,等待条件用于创建“睡眠”,因此 2 个代码的作用相同:等待大约 100 毫秒。这里的重要问题不是“我们要等待多少时间”,因为这是一个等待循环,而是“CPU 是否可以在等待期间处理其他任务”
  • @Aurelien - 在这两种情况下,当您的示例中的线程处于休眠状态时,CPU 都可以重新调度到其他线程,但您似乎忽略了条件变量的工作原理。如果在“其他”线程中有waitCondition.notifyOne(); 接近将someCondition 更改为true,则CV 等待将立即中断,而不是在时间用完时中断。
  • 我知道如何使用“等待条件”和“notifyOne”/“notifyAll”。唤醒是立即的,我经常将其用于消费者/生产者模式。在这个问题中,这里的重点是了解使用睡眠或“未使用”等待条件是否更有效(对于 CPU 调度)。
  • "sleep" 解决方案显然会定期将线程从睡眠队列移动到可运行队列,因此存在一些开销,而“等待”明确地将线程推入某个事件等待队列,直到事件到来。最糟糕的是,在“睡眠”中,您需要确保要测试的变量没有缓存到某个寄存器...
  • 谢谢,这就是我要找的答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-05-29
  • 1970-01-01
  • 2015-04-08
  • 2020-02-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多