对共享变量的无保护访问是否总是数据竞赛
Is unprotected access to shared variable always a data race?
假设x是一个共享的线程间变量,func总是返回0,那么下面的代码是否包含C11和C++11的数据竞赛?请假设x是在两个不同的线程中编写的,除了下面的switch语句外,始终使用适当的锁。
int x; // global variable
...
int y; // local variable
...
switch (func())
{
case 1:
{
x = 0;
y = 1;
break;
}
case 2:
{
x = 0;
y = 2;
break;
}
case 3:
default:
{
y = 3;
break;
}
}
标准(C11和C++11)中有一条注释,排除了编译器转换给代码引入数据竞争的可能性。编译器是否可以像下面这样转换代码?下面的代码当然包含数据竞赛,但问题是编译器是否引入了它,或者它是否已经在原始代码中。存在对共享变量的未受保护的访问,尽管无法访问。
int x; // global variable
...
int y; // local variable
...
temp = x;
x = 0;
switch (func())
{
case 1:
{
y = 1;
break;
}
case 2:
{
y = 2;
break;
}
case 3:
default:
{
x = temp;
y = 3;
break;
}
}
在C++标准中,定义了一个种族:
1.10/4:如果两个表达式求值中的一个修改内存位置,而另一个访问或修改相同的内存位置。
1.10/21:如果程序在不同线程中包含两个冲突操作,则程序的执行包含数据竞赛这不是原子性的,两者都没有发生在另一个之前。任何此类数据竞争会导致未定义的行为。
假设有几个线程运行相同的代码,由于func()
总是返回0(您的声明),没有一个线程可以更改x的内容。此外,y是线程执行的函数的局部变量,因此它是不共享的。因此,在这种情况下不可能出现竞争情况。
不允许编译器进行与第二个代码段相对应的转换,因为:
1.10/22:编译器转换,将赋值引入一个潜在的共享内存位置,该位置不会被抽象机器通常被本标准排除在外,因为一个赋值可能会覆盖其他线程的另一个赋值在抽象机器执行不会遇到数据竞争。
但是,如果您自己编写代码段,在上面解释的条件下,可能会遇到竞争条件,因为x不是原子,并且可能在一个线程(temp=x
)中有读取访问权限,在另一个线程中有写入访问权限(x=0
或在另一线程的默认部分(x=temp
)
- C++:在多个线程中访问同一数组/向量的不同单元格是否会产生数据竞赛?
- 潜在的数据竞赛是数据竞赛吗?
- 并行std::for_each中的数据竞赛
- 在 DirectX 中跨线程传递纹理的数据竞赛
- 仅当数据竞赛存在与锁定时,OpenMP关键部分
- 什么形式上保证了非原子变量不能看到凭空出现的值,并像理论上原子一样创造数据竞赛?
- std::future::wait 是内存障碍吗?(我无法解释这种数据竞赛)
- 加入线程后,是访问共享数据的数据竞赛吗?
- C++ mac OS X El Capitan上的openmp,Valgrind错误(数据竞赛)
- 确定是否将对象分配在静态内存块中(还是如何避免数据竞赛条件)
- C++shared_ptr和threadsantiazer报告数据竞赛
- C++内存模型——这个例子包含数据竞赛吗
- OpenMP C++与zheevr的数据竞赛
- 对共享变量的无保护访问是否总是数据竞赛
- ThreadSanitizer说我的spin_lock有数据竞赛,但如何
- 数据竞赛?段错误,但问题在哪里
- 集成瓦尔格林德输出以找出数据竞赛的位置
- c++openmp shared_ptr数据竞赛
- 使用原子<bool>的简单自旋锁中的数据竞赛
- CUDA还原和样本:数据竞赛