原子 bool 变量的一条语句中的多重赋值
Multiple assignment in one statement for atomic bool variables
继 Multiple assignment in one line 之后,我很想知道它如何适用于原子数据类型,特别是布尔类型的示例。
给定:
class foo {
std::atomic<bool> a;
std::atomic<bool> b;
public:
void reset();
[...] //Other methods that might change a and b
}
有什么区别吗:
void foo::reset() {
a = false;
b = false;
}
并且:
void foo::reset() {
a = b = false;
}
即第二种情况,会不会在b
赋值false
之后,另一个线程在b
之前将b
设置为true
被读取以将其值赋给 a
,因此在指令结束时 a
的值是 true
?
(这也意味着后一个版本似乎效率较低)
两者之间的差别很小。唯一真正的区别是分配顺序被翻转了。如果你打开优化,它是无法区分的。
是的,有区别
a = false;
b = false;
和
a = b = false;
如果 a
和 b
是原子的。由于赋值是从右向左进行的,所以后者相当于
b = false;
a = false; // since atomic::operator= (from above) returns its argument
与第一个版本不同,因为 a
和 b
是原子的,而 assignment is done as if std::atomic::store
was called with the memory order memory_order_seq_cst
. Thereby, the memory model guarantees
a single total modification order of all atomic operations that are so tagged.
因此,第二个线程执行原子加载 (bool a_observed = a.load(); bool b_observed = b.load();
) reverse 存储顺序 (a = b = false;
) 可以通过以下三种方式之一观察变化:
b
和 a
的旧值
- 加载
a
,加载b
,存储b
,存储a
b
的新值和 a
的旧值
- 存储
b
,加载 a
,存储 a
,加载 b
- 存储
b
,加载a
,加载b
,存储a
- 加载
a
、存储 b
、存储 a
、加载 b
- 加载
a
、存储 b
、加载 b
、存储 a
b
和 a
的新值
- 存储
b
、存储 a
、加载 a
、加载 b
相比之下,memory_order_seq_cst
在 a
之前存储 b
而(在另一个线程中)在 b
之前加载 a
保证 以下从未观察到:
a
的新值和 b
的旧值
继 Multiple assignment in one line 之后,我很想知道它如何适用于原子数据类型,特别是布尔类型的示例。
给定:
class foo {
std::atomic<bool> a;
std::atomic<bool> b;
public:
void reset();
[...] //Other methods that might change a and b
}
有什么区别吗:
void foo::reset() {
a = false;
b = false;
}
并且:
void foo::reset() {
a = b = false;
}
即第二种情况,会不会在b
赋值false
之后,另一个线程在b
之前将b
设置为true
被读取以将其值赋给 a
,因此在指令结束时 a
的值是 true
?
(这也意味着后一个版本似乎效率较低)
两者之间的差别很小。唯一真正的区别是分配顺序被翻转了。如果你打开优化,它是无法区分的。
是的,有区别
a = false;
b = false;
和
a = b = false;
如果 a
和 b
是原子的。由于赋值是从右向左进行的,所以后者相当于
b = false;
a = false; // since atomic::operator= (from above) returns its argument
与第一个版本不同,因为 a
和 b
是原子的,而 assignment is done as if std::atomic::store
was called with the memory order memory_order_seq_cst
. Thereby, the memory model guarantees
a single total modification order of all atomic operations that are so tagged.
因此,第二个线程执行原子加载 (bool a_observed = a.load(); bool b_observed = b.load();
) reverse 存储顺序 (a = b = false;
) 可以通过以下三种方式之一观察变化:
b
和a
的旧值- 加载
a
,加载b
,存储,b
存储a
- 加载
b
的新值和a
的旧值- 存储
b
,加载a
,存储,加载a
b
- 存储
b
,加载a
,加载b
,存储a
- 加载
a
、存储b
、存储、加载a
b
- 加载
a
、存储b
、加载b
、存储a
- 存储
b
和a
的新值- 存储
b
、存储a
、加载a
、加载b
- 存储
相比之下,memory_order_seq_cst
在 a
之前存储 b
而(在另一个线程中)在 b
之前加载 a
保证 以下从未观察到:
a
的新值和b
的旧值