Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/70.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 - Fatal编程技术网

C语言中位字段的并发更新

C语言中位字段的并发更新,c,C,C标准第3.15.3节规定: “同时更新中的两个非原子位字段是不安全的 如果在它们之间声明的所有成员也是 非零长度的位字段,无论其大小如何 中间的位字段正好是。” 考虑以下示例: struct S { unsigned a: 8; unsigned b: 4; unsigned c: 4; unsigned d: 8; }; 根据该标准,同时更新位字段a和d是不安全的 为什么不呢?位字段不能单独寻址,因此要设置位字段,编译器会将机器代码设置为: 读取包含要设置的位的字节 在该字

C标准第3.15.3节规定:

“同时更新中的两个非原子位字段是不安全的 如果在它们之间声明的所有成员也是 非零长度的位字段,无论其大小如何 中间的位字段正好是。”

考虑以下示例:

struct S {
  unsigned a: 8;
  unsigned b: 4;
  unsigned c: 4;
  unsigned d: 8;
};
根据该标准,同时更新位字段
a
d
是不安全的


为什么不呢?

位字段不能单独寻址,因此要设置位字段,编译器会将机器代码设置为:

  • 读取包含要设置的位的字节
  • 在该字节中设置所需的位
  • 将整个字节写回
  • 有时这是在一条指令中完成的,但处理器执行相同的任务

    无论哪种方式,如果另一个线程同时对同一字节中的其他位执行相同的操作,那么这两个线程的操作可能会相互干扰


    另外请注意:访问单位不能依赖于字节,例如,它可以是一个完整的
    int
    无符号的

    我知道位字段不能单独寻址。但我不明白为什么标准上说“无论大小”。如果上面的位字段b和c的大小是,比如说64和64(在这里组成),标准说同时更新a和d(它们之间的间隔超过16字节)是不安全的。所以,它并没有明确回答这个问题。好吧,处理器使用128位以上的字的时候可能会有,也可能会有。仅仅因为我们的普通CPU有64位宽度,而且大多数人认为这已经足够了,所以这不需要刻在石头上。我认为标准不想设置限制。@user3124390它说“无论大小”,因为另一种选择是提供与特定大小图案分离的保证。这将是复杂的,并且将意味着标准不希望做出的实现选择。相反,它们为您提供了明确的机制来分隔它们——0大小的位字段。这很有意义。