1

我正在管理一个包含 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. 可能 flags[4] 对于 uint32_t 读取未对齐,并且可能会导致未对齐的崩溃,或者由于未对齐的访问,可能无法保证原子功能。

  2. 字节序呢?应该出现问题吗?即使我使用的是 uint32_t,但我稍后会将其转换回 uint8_t 数组,并且我认为不会因为此操作而更改内存布局 - 不过,也许我在这里遗漏了一些东西。我在这里假设如果我读取 4 个字节的内存位置,无论您的机器是小端还是大端,这些模式在回退之前都是相同的。

  3. 有没有更好的方法来管理 uint8_t 的 4 个独立标志,但仍然能够以可移植的安全方式使用一个操作整体读取它们?

4

1 回答 1

2

将您的标志放在一个联合中:

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

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

这解决了对齐问题,您可以使用类型双关语来访问标志,t而无需强制转换。根据严格的 ISO C 规则,不是很干净,但通常会做你想做的事。

当您分配文字值(如我的示例中)或在访问flags.t. 只需读取一个值,然后写入一个刚刚读取的值(未修改 - 没有一点玩弄!)应该没问题。

于 2013-07-09T20:24:45.303 回答