C++ 11 您可以通过不同线程中的引用安全地传递和访问 std::atomics 吗?
C++ 11 can you safely pass and access std::atomics by reference in different threads
我想知道您是否可以通过引用线程来传递原子,并且对于 .load 和 .store 操作仍然是线程安全的。例如:
#include <thread>
#include <atomic>
#include <cstdlib>
void addLoop(std::atomic_int& adder)
{
int i = adder.load();
std::srand(std::time(0));
while(i < 200)
{
i = adder.load();
i += (i + (std::rand() % i));
adder.store(i);
}
}
void subLoop (std::atomic_int& subber)
{
int j = subber.load();
std::srand(std::time(0));
while(j < 200)
{
j = subber.load();
j -= (j - (std::rand() % j));
subber.store(j);
}
}
int main()
{
std::atomic_int dummyInt(1);
std::thread add(addLoop, std::ref(dummyInt));
std::thread sub(subLoop, std::ref(dummyInt));
add.join();
sub.join();
return 0;
}
当 addLoop 线程将新值存储到原子中时,如果 subLoop 使用加载和存储函数访问它,它最终会成为未定义的状态吗?
根据 [intro.races]/20.2,
如果程序的执行包含两个潜在的并发冲突操作,则程序的执行包含数据争用, 其中至少一个不是原子的,并且两者都不会先于另一个发生,除了 信号处理程序如下所述。任何此类数据争用都会导致未定义的行为。
根据[介绍种族]/2,
如果两个表达式计算修改内存位置 (4.4),另一个表达式读取 或修改相同的内存位置。
通过引用访问原子变量不会引入任何其他访问或修改,因为引用不占用内存位置。因此,当通过引用执行潜在的并发原子操作时,执行这些操作仍然是安全的。
事实上,在C++的抽象评估模型中,通过名称访问对象与通过绑定到该对象的引用变量访问对象之间没有区别。两者都只是指对象的左值。
当心std::atomic_init
函数,它是非原子的:
std::atomic<int> x;
void f(std::atomic<int>& r) {
std::atomic_init(&r, 0);
}
void g(std::atomic<int>& r) {
r = 42;
}
在上面的代码中,如果f
和g
在不同的线程中运行并且都访问原子变量x
,则可能会发生数据争用,因为其中一个操作不是原子的。但是,这与触发数据竞争没有什么不同:
std::atomic<int> x;
void f() {
std::atomic_init(&x, 0);
}
void g() {
x = 42;
}
不涉及引用的地方。
相关文章:
- 我想访问std::unique_ptr中的一个特定元素
- 通过unique_ptr访问std::数组
- 访问 std:vector 的类成员 std:vector 在一个类中与另一个 std:vector
- 使用 at() 访问 std::map 元素是否比运算符 [] 慢?
- 通过作为指向 C++ 函数的指针传递来访问 std::array 元素的正确方法是什么?
- 阻止直接访问 std::map 键
- 使用 std::get 访问 std::variant<index>
- 通过引用传递时访问std::vector的元素
- 如何访问std::shared_ptr方法
- SFML访问std::vector内的数组
- 无法访问 std::p air 的成员秒
- 访问"std::vector"的保留但未调整大小的内存作为原始内存是否安全?
- 如何访问"std::variant"的任何子级的"多态"基类?
- 访问 std::multimap 值的最佳方式?
- 如何在C++中从模板化类访问 std::vector 数据
- 在VS2015中访问std::any
- 在 c++ 中访问 std::map 的多个线程
- 在 Valgrind 输出中仍然可以访问 std 线程向量的块
- 用指针访问std ::字符串中的元素
- 在 C++ 中访问 std::array<std::array> 元素