【发布时间】:2014-09-05 22:58:51
【问题描述】:
假设我们有一个包含 uint8_t 字段的 C 结构:
typedef struct foo_s {
uint8_t field;
// other fields...
} foo_t;
如果我们想使用特定的内存顺序在field 中原子地存储一个值,C 语言中有哪些可能性?根据我的研究
-
C11 standard 不允许在非原子整数类型中进行原子存储 (
atomic_store_explicit)。最重要的是,标准中没有保证宽度为一个字节的原子整数类型。 - 另一种可能性(在 C11 内)是使用内存栅栏 (
atomic_thread_fence),然后将值存储在field中。但是标准要求这个 store 是 atomic 才能让栅栏按预期工作,所以我们回到上一项中描述的问题。
所以我们的问题的解决方案似乎超出了 C 标准...是否有任何常用的机制来原子存储字节?
请注意,我们无法更改field 的类型,因为它属于第三方库。
【问题讨论】:
-
是互斥体选项还是第三方库在不锁定的情况下从字段读取?
-
@delnan 理想情况下,不会有锁定。生产者将自动存储该值,而消费者将自动加载它。
-
但是可以锁定吗?因为它看起来确实是唯一可行的解决方案(几乎可以肯定有一个复杂的算法没有明确使用锁,但有效地重新实现了自旋锁或其他一些原始工具,但这更不可取)。 AFAIK 甚至没有对原子 8 位写入的硬件支持。
-
@delnan 无法锁定。关于硬件支持,软件原子存储操作可能基于原子 4 字节硬件存储,并使用比较和交换仅修改第一个字节(参见 Doug Currie 的回答)。
-
我假设练习的目的是向结构中的其他项目写入内容,然后将“字段”设置为完成信号...如果“字段”是原子的,那将是商店发布。问题似乎是没有办法确保写入“字段”发生在写入其他项目之后:-(我想知道
atomic_thread_fence(memory_order_seq_cst)在这里是否有帮助?[如果文档原子是在考虑程序员的情况下编写的,世界会变得更美好,恕我直言。]
标签: c multithreading gcc atomic memory-model