让线程等待值在内存中更改的有效方法?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了让线程等待值在内存中更改的有效方法?相关的知识,希望对你有一定的参考价值。
出于某些愚蠢的原因,我的(GNU / Linux)机器上有一块硬件只能通过向内存写入值来传达某种情况。假设通过一些魔术,硬件写入的内存区域对于我正在运行的进程是可见的。现在,我希望在该进程中有一个线程跟踪该值,并在更改后尽快执行 - 执行一些代码。但是,对我来说更重要的是线程不浪费CPU时间而不是绝对最小化响应延迟。所以 - 没有忙着等待一个不稳定的......
我应该如何做到这一点(使用现代C ++)?
笔记:
- 我不介意涉及原子或同步机制的解决方案(事实上,这可能是更可取的) - 只要你记住硬件不支持主机内存上的原子操作 - 它执行普通写操作。
- 硬件写入的值可以是我喜欢的值,也可以是它写入的内存位置中的初始值。
- 我使用C ++ 11,因为它是Modern C ++的流行标签,但实际上,C ++ 14很棒,C ++ 17也没问题。另一方面,即使是基于C的解决方案也可以。
答案
所以,天真的事情就是非忙碌的睡觉,例如:
volatile int32_t* special_location = get_special_location();
auto polling_interval_useconds = perform_tradeoff_between_accuracy_and_cpu_load();
auto polling_interval = std::chrono::microseconds(interval_in_usec);
while(should_continue_polling()) {
if (*special_location == HardwareIsDone) {
do_stuff();
return;
}
std::this_thread::sleep_for(polling_interval);
}
另一答案
这通常是通过std::condition_variable完成的。
...只要你记住硬件不支持主机内存上的原子操作 - 它执行普通写操作。
在这种情况下,std::atomic
的实现可能会回归到互斥体
UPD - 可能的实现细节:假设您有以下形式的某些数据结构:
struct MyData {
std::mutex mutex;
std::condition_variable cv;
some_user_type value;
};
并且您可以从多个进程访问它。编写器进程覆盖值并通过cv
通知notify_one,waits上的读取器进程cv
有点类似于忙等待方式,但是等待持续时间的线程收益。我可以添加的所有其他内容已经存在于所引用的示例中。
以上是关于让线程等待值在内存中更改的有效方法?的主要内容,如果未能解决你的问题,请参考以下文章
需要一种有效的方法来避免使用 Laravel 5 重复代码片段
JUC并发编程 共享模式之工具 JUC CountdownLatch(倒计时锁) -- CountdownLatch应用(等待多个线程准备完毕( 可以覆盖上次的打印内)等待多个远程调用结束)(代码片段