std::promise::set_value() 和 std::future::wait() 是不是提供内存围栏?

Posted

技术标签:

【中文标题】std::promise::set_value() 和 std::future::wait() 是不是提供内存围栏?【英文标题】:Do std::promise::set_value() and std::future::wait() provide a memory fence?std::promise::set_value() 和 std::future::wait() 是否提供内存围栏? 【发布时间】:2022-01-15 06:31:27 【问题描述】:

如果我执行以下操作:

std::promise<void> p;
int a = 1;

std::thread t([&] 
  a = 2;
  p.set_value();
);

p.get_future().wait();

// Is the value of `a` guaranteed to be 2 here?

cppreference 对set_value() 有这样的说法,但我不确定它是什么意思:

调用此函数不会与调用 get_future 引入数据竞争(但它们不需要相互同步)。

set_value()wait() 是否提供获取/释放同步(或其他形式)?

【问题讨论】:

【参考方案1】:

根据我的阅读,我相信 a 保证在最后是 2。请注意有关promise itself 的信息(强调我的):

promise 是 promise-future 通信通道的“推送”端:在共享状态下存储值的操作同步(定义在 std::memory_order 中)任何函数的成功返回正在等待共享状态(例如 std::future::get)。 否则,对同一共享状态的并发访问可能会发生冲突:例如 std::shared_future::get 的多个调用者必须要么都是只读或提供外部同步。

当然,我鼓励您阅读同步的含义。对于这种情况,这意味着set_value 被视为线程间发生之前,因此从我写的a 来看,这是一个可见的副作用。你可以找到更多here。

你对get_future 的评价是什么意思?这意味着您可以安全地从不同的线程调用get_futureset_value,它不会破坏任何东西。但它本身也不一定会引入任何内存栅栏。唯一确定且安全的同步点是来自std::promiseset_value 和来自std::futureget

【讨论】:

以上是关于std::promise::set_value() 和 std::future::wait() 是不是提供内存围栏?的主要内容,如果未能解决你的问题,请参考以下文章