mrn*_*mrn 5 c c++ multithreading c++11 c11
假设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;
}
}
Run Code Online (Sandbox Code Playgroud)
标准中有一个注释(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;
}
}
Run Code Online (Sandbox Code Playgroud)
在 C++ 标准中,定义了竞争:
1.10/4:如果两个表达式求值之一修改内存位置,而另一个表达式求值访问或修改同一内存位置,则两个表达式求值会发生冲突。
1.10/21:如果程序的执行在不同线程中包含两个冲突的操作,则该程序的执行包含数据争用,并且至少其中一个不是原子的,并且两者都没有在另一个之前发生。任何此类数据竞争都会导致未定义的行为。
假设您有多个线程运行相同的代码,由于func()总是返回 0(您的声明),因此没有一个线程可以更改 x 的内容。此外,y是线程执行的函数的局部变量,因此它不是共享的。因此,在这种情况下不会发生竞争条件。
不允许编译器进行与第二个片段相对应的转换,因为:
1.10/22:此标准通常排除将赋值引入到抽象机不会修改的潜在共享内存位置的编译器转换,因为在抽象机的情况下,这样的赋值可能会覆盖不同线程的另一个赋值执行不会遇到数据竞争。
temp=x但是,如果您自己编写代码片段,则在上面解释的条件下可能会遇到竞争条件,因为 x 不是原子的,并且一个线程 ( )中可能存在读取访问权限,而另一个线程中可能存在写入访问权限(x=0或者在另一个线程的默认部分中)线 (x=temp)
| 归档时间: |
|
| 查看次数: |
383 次 |
| 最近记录: |