当前位置: 首页 > 知识库问答 >
问题:

线程睡眠VS等待条件

司马同
2023-03-14

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

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

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

第一个使用“睡眠”,第二个使用“等待条件”。它们是用Qt编写的,但可以很容易地翻译成C 11、Boost或任何线程库。

两者都很好用,但是性能有什么不同吗?我记得我在某个地方读到过:

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

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

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

“睡眠”版本:

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

// Do some work

“WaitContions”版本:

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

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

// Do some work

共有1个答案

於炯
2023-03-14

编辑:

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

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

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

原件:

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

 类似资料:
  • 我正在编写一个基于await/sleep范式的网络绑定应用程序。 我更喜欢这样一个答案,不创建任何额外的线程

  • 上面的代码工作得很好,但如果我使用wait而不是thread。sleep I get StaleElementReferenceException异常。这是我使用的流畅等待: 这将找到combobox,但再次对combobox执行任何操作将导致NoTouchElement或statestate异常。所以我也尝试了从combobox中选择值: 这超时和doesnot工作! 我如何才能使这项工作,为什

  • 首先,我没有问与C#相同的问题-线程的替代品。睡眠?,或线程的替代品。睡在C#?。我不认为我使用它是错误的,需要一个真正的替代特定的情况。 在一次代码分析运行中,我看到了一个令人惊讶的违规行为: 线程的用法。睡眠()是设计缺陷的标志。 这一违规行为导致彼得·里奇(Peter Richie)撰写了一篇文章,阐述了为什么这构成了糟糕的设计。 我们都知道线程创建是昂贵的,线程阻塞意味着池中的争用。我们还

  • 我正在使用Ruby和selenium webdriver gem创建一个web爬行/抓取脚本。我几乎完成了这个项目,但在某个点上卡住了,我正在抓取的站点用于对服务器的页面调用并显示一个字符串,问题是它显示了50%的时间,而不是100%。所以我需要循环get函数,直到它显示字符串。 我使用了隐式 我需要的是 好吧,我可以使用正常的睡眠10并且工作正常,但如果调用首先返回字符串,这是浪费时间

  • 我想实现这样的事情:用户按下登录按钮,然后标签显示:连接。 0.5秒时间间隔 连接... 0.5秒时间间隔 连接... 等 只是一种视觉效果,表明“引擎盖下”确实发生了什么。 我所得到的并不是我所期望的。我点击按钮,等待1.5秒,然后我得到了“连接…”,缺少前面的两个步骤。 首先,我的类 还有我的class

  • 我使用 C 和 POSIX 线程创建了一个多线程应用程序。我现在应该阻塞一个线程(主线程),直到设置了布尔标志(变为真)。 我找到了两种方法来完成这件事。 > 在没有睡眠的情况下旋转。 在睡眠中旋转循环。 如果我应该遵循第一种方式,为什么有些人编写代码遵循第二种方式?如果应该使用第二种方法,为什么要让当前线程Hibernate呢?这种方式的缺点是什么?