Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/158.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 在两个线程之间共享int时可能会出现什么问题?_C++ - Fatal编程技术网

C++ 在两个线程之间共享int时可能会出现什么问题?

C++ 在两个线程之间共享int时可能会出现什么问题?,c++,C++,两个线程访问一个共享int,x。指令重新排序等会产生什么问题 线程1: x = 1; 线程2: obj.f(x); 如果x是不稳定的,会发生什么变化? 如果线程1和线程2在不同的内核上运行,会发生什么变化?如果不同步线程,则在线程2的视图中,x的值可以随时更改 让我们看看: class A { public: A() { x = 0; } void set() { x = 1; } int f() { return x + x%2; } int x; }; 现在,如

两个线程访问一个共享int,x。指令重新排序等会产生什么问题

线程1:

x = 1;
线程2:

obj.f(x);
如果x是不稳定的,会发生什么变化?

如果线程1和线程2在不同的内核上运行,会发生什么变化?

如果不同步线程,则在线程2的视图中,x的值可以随时更改

让我们看看:

class A {
public:
   A() { x = 0; }
   void set() { x = 1; }
   int f() { return x + x%2; }
   int x;
};
现在,如果线程1调用
set
,线程2调用
f
,而没有同步,则f的结果是未定义的。它可以是0+0%2或1+0%2或1+1%2


线程运行的核心是什么或有多少并不重要。未使用显式线程同步时,未定义执行顺序。

如果不同步线程,则在线程2的视图中,x的值可以随时更改

让我们看看:

class A {
public:
   A() { x = 0; }
   void set() { x = 1; }
   int f() { return x + x%2; }
   int x;
};
现在,如果线程1调用
set
,线程2调用
f
,而没有同步,则f的结果是未定义的。它可以是0+0%2或1+0%2或1+1%2


线程运行的核心是什么或有多少并不重要。不使用显式线程同步化的情况下,不执行执行顺序。

<代码>代码> Value<代码>不是用于C++中的线程同步,而是为了避免某些编译器优化(参见:)/P> 如果您需要控制对x的访问,则需要使用互斥或原子


<> > >编辑:这里讨论了在没有互斥体的情况下发生的事情,即使只是一个int -< /p> < > >代码> < <代码> >,并不意味着C++中的线程同步,而是避免某些编译器优化(参见:)

如果您需要控制对x的访问,则需要使用互斥或原子

编辑:这里讨论了在没有互斥锁的情况下阅读时会发生什么,即使只有int-

两个线程访问一个共享int,
x
。指令重新排序等会产生什么问题

没有互斥?不要那样做,否则你将冒着鼻魔的危险。:-)确切地说,任何事情都可能发生。它甚至可能看起来有效(只要您不依赖一致的值)。但真的不要那样做

如果
x
声明为红色
volatile
,会发生什么变化

不会太多,或者可能行为会有所不同,但你仍然得不到你想要的东西。易失性变量用于处理内存映射设备之类的事情,而不是欺骗您通过CPU缓存

如果线程1和线程2在不同的内核上运行,会发生什么变化

问题会变得更糟(但您可能也不会立即看到任何差异)。如果没有互斥或信号量,就不会使用任何内存障碍;它们是使事情起作用的关键(同时还有一个适当的锁来阻止一个线程在另一个写的时候读或写),它们根本不属于标准C++。这就是为什么要使用正确的线程原语;他们为你解决这些棘手的问题

请注意,测试不能保证发现线程一致性问题;它们本质上接近比赛条件,发生的情况通常会根据系统负载而变化

两个线程访问一个共享int,
x
。指令重新排序等会产生什么问题

没有互斥?不要那样做,否则你将冒着鼻魔的危险。:-)确切地说,任何事情都可能发生。它甚至可能看起来有效(只要您不依赖一致的值)。但真的不要那样做

如果
x
声明为红色
volatile
,会发生什么变化

不会太多,或者可能行为会有所不同,但你仍然得不到你想要的东西。易失性变量用于处理内存映射设备之类的事情,而不是欺骗您通过CPU缓存

如果线程1和线程2在不同的内核上运行,会发生什么变化

问题会变得更糟(但您可能也不会立即看到任何差异)。如果没有互斥或信号量,就不会使用任何内存障碍;它们是使事情起作用的关键(同时还有一个适当的锁来阻止一个线程在另一个写的时候读或写),它们根本不属于标准C++。这就是为什么要使用正确的线程原语;他们为你解决这些棘手的问题


请注意,测试不能保证发现线程一致性问题;它们本质上接近竞赛条件,发生的情况通常会根据系统负载而变化。

我猜您的意思是,如果f将参数作为参考-f(int&value)?如果f被声明为f(int值),x将被复制到堆栈…@Tobbe-No。他试图解释x的值在线程2中是未知的,因为还不能保证它被设置为1。好的,这是一个竞争条件的示例。我实际上是指在单次写入(线程1)和单次读取(线程2)过程中可能出现的错误。但这可能不是很清楚……我猜你的意思是,如果f将参数作为参考-f(int&value)?如果f被声明为f(int值),x将被复制到堆栈…@Tobbe-No。他试图解释x的值在线程2中是未知的,因为还不能保证它被设置为1。好的,这是一个竞争条件的示例。我实际上是指在单次写入(线程1)和单次读取(线程2)过程中可能出现的错误。但这可能不是很清楚…原子或互斥是解决方案。但问题是如果我不保护变量会发生什么?你会得到未定义的行为。如果在修改x的同时读取线程2,那么最终会看到什么,这实际上是一个特定于平台的问题。原子或互斥是解决方案。但问题是如果我不保护变量会发生什么?你会得到未定义的行为。结果真的是