【发布时间】:2018-03-15 18:45:22
【问题描述】:
如下所示,我有一个包含几个位域的结构。我还有一个包含 volatile 64 位值和这个结构的联合。通过联合访问的结构的更改是否也是易变的?
即由于 struct 和 volatile int 共享相同的内存位置,对 struct 的访问是否也会导致每次访问都访问内存,还是编译器会将它们存储在寄存器中?
typedef struct {
uint64 my_info_1:12;
uint64 my_info_2:16;
uint64 reserved: 36;
} my_info_s;
typedef union {
my_info_s my_info_struct;
volatile unsigned long long my_info_vol; //64 bit
} my_info_u;
my_info_u my_info;
//Are these volatile accesses?
my_info.my_info_1 = 4;
my_info.my_info_2 = 8;
//This is the motivation- update a bunch of bitfields, but set them in one shot.
atomic_set(atomic_location, my_info.my_info_vol);
由于某些实时限制,我无法使用锁/互斥锁来实现此目的。
【问题讨论】:
-
stackoverflow.com/questions/4306186/… 你需要考虑填充。确保 sizeof(my_info_s) 为 64。
-
我不会想到将存储类放在结构或联合的单个成员上甚至是合法的,但我想它在语法上是有效的,因为在 or 中没有两个单独的声明语法结构之外。我认为它没有意义,但现在你问了,我不知道有什么反对它的规则。 (gcc,至少我尝试过的版本,似乎毫无怨言地接受了它们。)
-
易失位域是什么意思?在不影响结构的其他位的情况下,您无法真正读取或写入 12 位或 36 位。所以看起来像没有。
-
考虑结构的地址可以被获取并传递给另一个对联合一无所知的模块中的例程。此例程将仅看到非易失性
struct类型的定义,并且编译器在编译此例程时不会将其视为易失性。因此,对与 volatile 对象共享联合的结构的访问不能被认为是 volatile。 -
鉴于您的“我不能使用锁/互斥锁来实现这个......”,我希望您不要尝试使用
volatile来使您的代码线程安全,因为那不会工作。请参阅 Volatile: Almost Useless for Multi-Threaded Programming 和 Should volatile Acquire Atomicity and Thread Visibility Semantics? 请注意,第二作者正是 Hans Boehm。