混合原子和非原子变量和缓存
Posted
技术标签:
【中文标题】混合原子和非原子变量和缓存【英文标题】:mix atomic and non atomic variables and caches 【发布时间】:2017-08-15 08:50:23 【问题描述】:假设我们有这段代码是正确的(至少我希望如此):
std::atomic<int> a;
std::atomic<bool> readyfalse;
void threadA()
a.store(666, std::memory_order_relaxed);
ready.store(true, std::memory_order_release);
void threadB()
while(!ready.load(std::memory_order_acquire));
process(a.load(std::memory_order_relaxed));
我的问题是:如果您使用的是int a;
而不是std::atomic<int> a;
,它也正确吗?还是缓存刷新/失效的问题?
【问题讨论】:
如果你不得不问...使用顺序一致性。除非大量注释和封装,否则即使您了解自己在做什么,维护您的代码的人也不会。 它并不是针对特定用例的。它更多的是理论而不是其他东西;)。但是,此代码是否可以在顺序一致性下工作? 对我来说看起来不错。我鼓励你观看名为“原子武器”的讲座。在那之后,这一切对我来说都是有意义的。 youtube.com/watch?v=c1gO9aB9nbs 经典的“完整”模式,其中原子ready
变量扮演一个标志的角色,它保护其他变量的设置。受此机制保护的变量不必是原子的。 (也就是说,是的,你可以使用int a;
)。
【参考方案1】:
无论这是否是一个好主意,例如,您的代码很好..
您可以将 a
的原子类型替换为常规的 int
(或任何类型)。
C++ 标准使用以下短语(第 1.10.1-6 节)支持您的情况:
某些库调用与另一个线程执行的其他库调用同步。例如,原子存储释放与从存储中获取其值的加载获取同步
由于threadB
加载了threadA
存储的ready
的值(它在循环中等待它),synchronizes-with 关系就建立了。
因此,a.load()
观察到了a.store()
的记忆效应。另一种说法是 a.store()
happen-before a.load()
【讨论】:
是的,但我的问题更多的是:用非原子变量替换原子变量是否正确。你在一开始就回答了;)以上是关于混合原子和非原子变量和缓存的主要内容,如果未能解决你的问题,请参考以下文章