使用32位读取原子读取4个字节的数组

时间:2013-07-09 20:15:29

标签: c casting atomic

我正在管理一个由4个uint8_t标志组成的数组。

uint8_t flags[4].

这些标志随时可以通过不同的线程进行更改。

我希望能够通过一个原子操作获得这些标志的快照。 让我说我做以下事情:

uint32_t temp_val = read_atomic32((uint32_t *) &flags[0])

现在我回到了一系列标志:

uint8_t *my_flags = &temp_val;
printf("flag zero is %d\n, my_flags[0]);

我怀疑这里几乎没有问题:

  1. 也许标志[4]没有与uint32_t读取对齐,并且可能会导致非对齐崩溃 或者,由于访问不对齐,原子功能不会被占用。

  2. 端序员怎么样?如果出现问题?即使我正在使用uint32_t我稍后将其转换回uint8_t数组,我不认为内存布局会因为这个动作而改变 - 但是,也许我在这里遗漏了一些东西。 我在这里假设,如果我读取4字节的内存位置,无论你的机器是小端还是大端,这些模式都是相同的,直到退回。

  3. 有没有更好的方法来管理uint8_t的4个独立标志,但仍然能够以便携式安全方式使用一个动作完整地读取它们?

1 个答案:

答案 0 :(得分:2)

将你的旗帜放在一个联盟中:

union {
  uint8_t  c[4];
  uint32_t t;
} flags;

flags.c[0] = ...;
flags.t = 0xffffffffU;

这会解决对齐问题,您可以使用类型双关语来通过t访问标记而无需强制转换。根据严格的ISO C规则,不完全是犹太洁食,但通常会做你想要的。

当您分配文字值时(如我的示例中)或在访问flags.t时期望某些值时,字节顺序会成为问题。只是阅读一个值,然后写一个只读(未经修改 - 没有一点点!)应该没问题。