Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.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++ C++;11内存模型和在不同线程中访问同一结构的不同成员_C++_Multithreading_C++11_Thread Safety_Memory Model - Fatal编程技术网

C++ C++;11内存模型和在不同线程中访问同一结构的不同成员

C++ C++;11内存模型和在不同线程中访问同一结构的不同成员,c++,multithreading,c++11,thread-safety,memory-model,C++,Multithreading,C++11,Thread Safety,Memory Model,假设您有以下定义: struct X { char a, b; }; X x; 现在假设您有两个线程,其中一个读写x.a但从不访问x.b,而另一个读写x.b但从不访问x.a。两个线程都不使用任何锁或其他同步原语。这保证在C++11中工作吗?或者它被算作访问同一个对象,因此需要一个锁吗?它是安全的。引用C++11: [intro.memory]p3: 内存位置要么是标量类型的对象,要么是相邻位字段的最大序列,所有这些字段的宽度都不为零。[注:语言的各种功能,如引用和虚拟函数,可能涉及程序无

假设您有以下定义:

struct X
{
  char a, b;
};

X x;

现在假设您有两个线程,其中一个读写
x.a
但从不访问
x.b
,而另一个读写
x.b
但从不访问
x.a
。两个线程都不使用任何锁或其他同步原语。这保证在C++11中工作吗?或者它被算作访问同一个对象,因此需要一个锁吗?

它是安全的。引用C++11:

[intro.memory]p3:

内存位置要么是标量类型的对象,要么是相邻位字段的最大序列,所有这些字段的宽度都不为零。[注:语言的各种功能,如引用和虚拟函数,可能涉及程序无法访问但由实现管理的附加内存位置。-结束注]两个执行线程(1.10)可以更新和访问单独的内存位置,而不会相互干扰

[intro.memory]第5页:

[示例:声明为

包含四个独立的内存位置:字段
a
和位字段
d
e.ee
都是独立的内存位置,可以同时修改而不相互干扰。位字段
b
c
共同构成第四个内存位置。位字段
b
c
不能同时修改,但可以同时修改
b
a
。-结束示例]


这意味着
X
的成员
a
b
是独立的内存位置,因此可以同时访问。

没关系,它们是两个不同的位置。我会留给某人精力去证明它的答案。@Mat但C/C++中的每个对象/原语都必须至少有1个字节。1字节是“最小的可寻址单元”。答案就在那里,我想@Mat我记得在某个地方听到标准要求所有字段成员都有不同的地址。虽然这是我从聊天中听到的第三手信息。我将等待有人确认/拒绝它。请注意,尽管这是安全的,但可能会导致性能下降。这是什么?
:0
,这会强制设置字节边界吗?@WouterHuysentruit。这是一个零长度的位字段。引用
[class.bit]p2
:“作为一种特殊情况,宽度为零的未命名位字段指定下一位字段在分配单元边界处的对齐方式。”如果它是
无符号int c:11
而不是
int c:11
,该怎么办?位字段类型的更改是否重要?这是安全的。但是因为a和b在同一个缓存线中。当另一个线程上次写入时,每次读写都会导致性能下降,因为它需要刷新缓存线。
struct {
  char a;
  int b:5,
  c:11,
  :0,
  d:8;
  struct {int ee:8;} e;
}