简体   繁体   English

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

[英]read array of 4 bytes atomically using read of 32-bit

I am managing an array of 4 flags of uint8_t each. 我正在管理每个uint8_t 4标志的数组。

uint8_t flags[4].

these flags can change by different threads at any moment. 这些标志可以随时由不同的线程更改。

i want to be able to get a snapshot of these flags by using one atomic operation. 我希望能够使用一个原子操作来获取这些标志的快照。 lets say i do the following : 可以说我做以下事情:

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

now i cast back to an array of flags: 现在我回退到一组标志:

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

i am suspecting few problems here: 我怀疑这里有几个问题:

  1. maybe flags[4] is not aligned for uint32_t reads and might give a non-aligned crash or prehaps the atomic functionality will not be garunteed because of nonaligned access. 可能flags [4]不能与uint32_t读取对齐,并且可能会导致未对齐的崩溃,或者可能由于未对齐的访问而导致原子功能无法正常运行。

  2. what about endians? 那么字节序呢? should a problem occur? 应该发生问题吗? even though i am using uint32_t i am later on casting it back to an array of uint8_t and i don't think the memory layout will be changed because of this action - still, maybe i am missing something here. 即使我正在使用uint32_t,但我稍后将其强制转换回uint8_t数组,并且我不认为由于此操作会更改内存布局-仍然,也许我在这里缺少了一些东西。 i am assuming here that if i read a memory location for 4 bytes, these pattern will be the same until cast back no matter if your machine is little endian or big endian. 我在这里假设,如果我读取一个4字节的内存位置,则无论您的机器是小端字节序还是大端字节序,这些模式在返回之前都是相同的。

  3. is there a better way to manage 4 independent flags of uint8_t but still be able to read them as whole using one action in a portable safe way? 有没有更好的方法来管理uint8_t的4个独立标志,但仍然能够以一种可移植的安全方式使用一个动作将它们整体读取?

Place your flags in a union: 将您的标志放在联合中:

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

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

This takes care of the alignment issue and you can use the type punning to access the flags via t without a cast. 这可以解决对齐问题,您可以使用punning类型通过t访问标志,而无需强制转换。 Not quite kosher according to strict ISO C rules, but usually does what you want. 根据严格的ISO C规则,不是完全符合犹太标准,但通常会做您想要的。

Endianness becomes an issue the moment you assign literal values (as in my example) or expect certain values when accessing flags.t . 当您分配文字值(例如在我的示例中)或在访问flags.t时期望某些值时, flags.t成为一个问题。 Just reading a value and then writing one just read (unmodified--no bit twiddling!) should be okay. 只需读取一个值,然后再写入一个刚刚读取的值(未修改-不用花哨!)就可以了。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM