mat*_*att 2 c++ winapi multithreading
有时您会遇到这样的情况:一个线程需要等待,直到它从另一个线程获取信号。目前我通过以下方式实现这一点:(有一个volatile int signal;由另一个线程设置来告诉等待线程继续)
方法 1:本能地等待时延迟最低,但 cpu 使用率最高:
while(signal != 1);
Run Code Online (Sandbox Code Playgroud)
方法2:仍然使用100% cpu/core,但我认为更好的是给其他线程运行的机会?延迟仍然非常低
while(signal != 1) Sleep(0);
Run Code Online (Sandbox Code Playgroud)
方法3:等待时CPU使用率可以忽略不计(任务管理器中报告为0%),但明显有1ms的延迟。
while(signal != 1) Sleep(1);
Run Code Online (Sandbox Code Playgroud)
有没有更好的方法来处理这种情况?主要对原生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)
Run Code Online (Sandbox Code Playgroud)
如果您只希望在线程可以继续signal运行之前花费几毫秒(或类似顺序的时间),那么这可能是没问题的。true由于它等待的时间不是很长,因此在等待时不会占用大量 CPU 时间,并且(特别是在系统负载较轻的情况下)可以在signal变为时非常快速地响应true。
如果线程可能等待的时间超过几毫秒,那么您可能最好使用某种机制,该机制采用当前线程并将其标记为未准备好运行,而是在某个内核对象可以/将要运行之前等待它又预定了。WindowsEvent为此提供了 s:
HANDLE signal = CreateEvent(/* ... */);
WaitForSingleObject(signal, INFINITE);
Run Code Online (Sandbox Code Playgroud)
当其他代码想要发出该线程应该运行的信号时,它会执行以下操作:
SetEvent(signal);
Run Code Online (Sandbox Code Playgroud)
对于这个简单的情况,Windows 事件可能工作得很好,但在复杂的情况下,获得你想要的东西可能会在困难和完全不可能之间徘徊(尽管大多数情况变得困难实际上是因为你可能应该使用除一个事件)。
您还可以使用标准库中的条件变量,但它有点复杂。条件变量始终与互斥体以及您关心的条件结合使用。因此,将它用于您的情况看起来有点像这样:
std::atomic<bool> signal;
std::mutex m;
std::condition_variable v;
std::unique_lock<std::mutex> lock(m);
v.wait(lock, [&] { return signal; });
Run Code Online (Sandbox Code Playgroud)
...对于其他代码来表明该线程可以继续,它会执行以下操作:
std::unique_lock<std::mutex> lock(m);
signal = true;
v.notify_one();
Run Code Online (Sandbox Code Playgroud)
条件变量确实有优点,但无论如何它都不是最简单的使用方式。另一方面,一旦您习惯了所涉及的样板,它也不是特别困难。
| 归档时间: |
|
| 查看次数: |
14732 次 |
| 最近记录: |