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

时间:2018-03-25 22:45:53

标签: c++ linux multithreading c++11 synchronization

出于某种愚蠢的原因,我的(GNU / Linux)机器上有一块硬件只能通过向内存写入值来传达某种情况。假设通过一些魔术,硬件写入的内存区域对于我正在运行的进程是可见的。现在,我希望在该进程中有一个线程跟踪该值,并在更改后尽快执行 - 执行一些代码。但是,对我来说更重要的是线程不浪费CPU时间而不是绝对最小化响应延迟。所以 - 不要忙着等待一个不稳定的......

我应该如何做到这一点(使用现代C ++)?

注意:

  • 我不介意涉及原子或同步机制的解决方案(事实上,这可能更可取) - 只要你记住硬件不支持主机内存上的原子操作 - 它执行一个普通的写作。
  • 硬件写入可以是我喜欢的任何内容,也可以是它写入的内存位置的初始值。
  • 我使用的是C ++ 11,因为它是Modern C ++的流行标签,但实际上,C ++ 14很棒,C ++ 17也没问题。另一方面,即使是基于C的解决方案也可以。

2 个答案:

答案 0 :(得分:0)

所以,天真的事情就是非忙碌的睡眠,例如:

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); 
}

答案 1 :(得分:-1)

这通常是通过std::condition_variable完成的。

  

...只要您记住硬件不支持主机内存上的原子操作 - 它就会执行普通写操作。

在这种情况下,std::atomic的实现可能会回归到互斥锁

UPD - 可能的实现细节:假设您有以下形式的数据结构:

struct MyData {
    std::mutex mutex;
    std::condition_variable cv;
    some_user_type value;
};

您可以从多个进程访问它。 Writer进程会覆盖值并通过notify_one通过cvcv上的读取器进程waits以类似于忙等待的方式通知undefined,但是等待持续时间的线程收益。我可以添加的其他内容已经存在于所引用的示例中。