【发布时间】:2018-07-11 03:23:44
【问题描述】:
我想知道您是否可以通过引用线程来传递原子,并且 .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 线程将新值存储到 atomic 时,如果 subLoop 使用 load 和 store 函数访问它,它最终会成为未定义状态吗?
【问题讨论】:
-
您的代码有问题,` j -= (j - (std::rand() % j));` 可能会使 j=0,然后出现被零除的错误。
-
使用
std::thread参数的别名与引用单个全局对象的多个线程的工作方式没有任何不同——设置引用相对于启动线程是严格排序的,所以你肯定是别名std::atomic对象正确。之后,取决于对象如何处理并发访问(对于std::atomic很好,对于大多数其他类型甚至不要尝试)
标签: c++ multithreading c++11 pass-by-reference atomic