gpt4 book ai didi

c++ - C++ 中 volatile 的合法用例?

转载 作者:行者123 更新时间:2023-11-30 01:35:06 26 4
gpt4 key购买 nike

我正在运行几个线程,它们基本上都返回相同的对象作为结果。然后我就等全部完成,基本看结果。为避免需要同步,我认为我可以将所有结果对象预先分配到数组或 vector 中,并为线程提供指向每个对象的指针。在高层次上,代码是这样的(简化):

std::vector<Foo> results(2);
RunThread1(&results[0]);
RunThread2(&results[1]);
WaitForAll();
// Read results
cout << results[0].name << results[1].name;

基本上我想知道这个“代码”是否有任何潜在的不安全。我想知道的一件事是 vector 是否应该声明为 volatile,这样末尾的读取就不会被优化并输出不正确的值。

最佳答案

对您的问题的简短回答是否定的,数组不应声明为 volatile。出于两个简单的原因:

  1. 不需要使用 volatile。每个健全的多线程平台都提供具有明确定义的语义的同步原语。如果您使用它们,则不需要 volatile

  2. 使用 volatile 是不够的。由于 volatile 没有在您可能使用的任何平台上定义多线程语义,因此它本身不足以提供同步。

最有可能的是,无论您在 WaitForAll 中做什么就足够了。例如,如果它使用事件、互斥锁、条件变量或几乎任何类似的东西,它将定义足以使其安全的多线程语义。

更新:“出于好奇,WaitForAll 中保证读取安全的事情的示例是什么?它不需要有效地告诉编译器以某种方式“刷新“缓存还是避免后续读取操作的优化?”

好吧,如果你正在使用 pthreads,那么如果它使用 pthread_join 这将是一个保证读取安全的例子,因为文档说线程所做的任何事情对线程可见在 pthread_join 返回后加入它。

它是如何做的是一个实现细节。实际上,在现代系统上,没有要刷新的缓存,也没有任何可能但需要避免的后续读取优化。

考虑是否在 WaitForAll 的深处调用了 pthread_join。通常,您只是不让编译器查看 pthread_join 的内部结构,因此编译器必须假定 pthread_join 可能会执行其他线程可以执行的任何操作。因此,将另一个线程可能在调用 pthread_join 时修改的信息保存在寄存器中是非法的,因为 pthread_join 本身可能会访问或修改该数据。

关于c++ - C++ 中 volatile 的合法用例?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54837438/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com