让线程等待值在内存中更改的有效方法?

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_onewaits上的读取器进程cv有点类似于忙等待方式,但是等待持续时间的线程收益。我可以添加的所有其他内容已经存在于所引用的示例中。

以上是关于让线程等待值在内存中更改的有效方法?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用Javascript等待值在html中更改[重复]

需要一种有效的方法来避免使用 Laravel 5 重复代码片段

等待线程在shutdownhook中写入更改

JUC并发编程 共享模式之工具 JUC CountdownLatch(倒计时锁) -- CountdownLatch应用(等待多个线程准备完毕( 可以覆盖上次的打印内)等待多个远程调用结束)(代码片段

java多线程(线程通信-等待换新机制-代码优化)

java线程基础梳理