等待线程的最佳方式是什么
What is the best way to wait a thread?
有时会出现这样的情况,即线程需要等待,直到它从另一个线程获得信号。目前我通过以下方式实现这一点:(有一个volatile int signal;
由另一个线程设置,用于告诉等待的线程继续(
方法1:本能地最低延迟,但等待时最高cpu使用率:
while(signal != 1);
方法2:仍然使用100%cpu/core,但我认为更善于给其他线程一个运行的机会?仍然非常低延迟的
while(signal != 1) Sleep(0);
方法3:等待时cpu使用率可以忽略不计(在任务管理器中报告为0%(,但显然有1ms的延迟。
while(signal != 1) Sleep(1);
有更好的方法来处理这个案子吗?主要对本机c++Win32感兴趣,但也对linux/android/ios感兴趣。
如果没有神奇的低延迟/低等待cpu使用率解决方案,我对以下两种情况下的最低延迟解决方案都感兴趣:等待cpu使用量无关紧要,等待cpu使用应该可以忽略不计。
如果这是一个小问题,我很抱歉,但我对这种事情还不熟悉。
;右";这里的答案取决于您对延迟和吞吐量的重视程度——也就是说,这个特定线程在发出信号后尽快开始处理更重要,还是其他线程在等待时获得最大的CPU时间更重要?在很多情况下,所需的内容还取决于线程在准备好继续之前等待的时间。
现在,您正在进行繁忙的等待——也就是说,在等待期间,您在一定程度上保持CPU(至少有一个核心(繁忙,检查它是否可以继续。
执行Sleep(0)
基本上将当前线程放在准备执行并等待CPU执行的线程队列的后面。因此,如果没有其他线程在等待,它仍然会消耗100%的CPU。另一方面,如果具有相同优先级的其他线程已准备好运行,则它们将有机会在再次调度此线程之前运行。
不过有一点:volatile
并没有像这样真正为线程间通信定义,所以您希望使用原子变量。
std::atomic<bool> signal { false };
while (!signal)
Sleep(0); // or Sleep(1)
如果在signal
变成true
之前只需要几毫秒(或按这个顺序(,那么线程就可以继续了。由于它等待的时间不长,因此在等待期间不会占用大量CPU时间,而且(尤其是在系统负载较轻的情况下(当signal
变为true
时,它可以非常快速地做出响应。
如果线程等待的时间可能超过几毫秒,那么您最好使用一些机制来获取当前线程并将其标记为未准备好运行,而是在某个内核对象上等待,然后才能/将其再次调度。Windows为此提供Event
:
HANDLE signal = CreateEvent(/* ... */);
WaitForSingleObject(signal, INFINITE);
当其他代码想要发出这个线程应该运行的信号时,它会执行如下操作:
SetEvent(signal);
对于这种简单的情况,Windows事件可能工作得很好,但在复杂的情况下,获得你想要的东西可能会在困难和完全不可能之间徘徊(尽管大多数情况下变得困难是因为你可能应该使用事件以外的东西(。
您也可以使用标准库中的条件变量,但它有点复杂。条件变量总是与互斥对象以及您关心的条件一起使用。所以在你的案例中使用它会看起来有点像这样:
std::atomic<bool> signal;
std::mutex m;
std::condition_variable v;
std::unique_lock<std::mutex> lock(m);
v.wait(lock, [&] { return signal; });
如果其他代码发出信号表示这个线程可以运行,它会执行以下操作:
std::unique_lock<std::mutex> lock(m);
signal = true;
v.notify_one();
条件变量确实有优点,但无论如何,它都不是最简单的使用方法。另一方面,一旦你习惯了所涉及的样板,这也不是特别困难。
- 使用QQuickFramebufferObject时同步数据的最佳方式是什么
- 在reactor中存储eventHandlers的最佳方式是什么
- 引用 std::any 或 not_yet_in_std::whatever 的惯用方式是什么?
- 在C++中,建议通过数组循环的方式是什么?
- DLL共享数据的推荐方式是什么
- 等待线程的最佳方式是什么
- 将uint8_t*buffer和size_tbufferlen从C++传递到C中的API函数的最佳方式是什么
- 只显示片段着色器的最佳方式是什么
- 复制文件的最佳方式是什么,以便我可以在复制过程中轻松取消复制?
- 在 c++ 中打印到控制台的最佳方式是什么?
- 在Qt Creator中应用代码更改的快捷方式是什么?
- 在C 中超负荷构造函数的合适方式是什么
- 执行随机开关函数的QT方式是什么连续两次使用相同情况的方法
- 在某些代码中覆盖方法的方式是什么?
- 为单个函数同时声明多个变量的最佳方式是什么
- Qt中数据类(模型)和视图/控制器类之间的数据通信的正确方式是什么
- 在c++中存储一个对象或不存储对象的首选方式是什么
- 在C 项目中包含库的不同方式是什么?
- 解释"Bit String"的最佳方式是什么
- 计算差异数据并通过网络发送的最佳方式是什么