- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我正在研究这个网站:https://gcc.gnu.org/wiki/Atomic/GCCMM/AtomicSync ,这对理解关于原子类的话题非常有帮助。
但是这个放松模式的例子很难理解:
/*Thread 1:*/
y.store (20, memory_order_relaxed)
x.store (10, memory_order_relaxed)
/*Thread 2*/
if (x.load (memory_order_relaxed) == 10)
{
assert (y.load(memory_order_relaxed) == 20) /* assert A */
y.store (10, memory_order_relaxed)
}
/*Thread 3*/
if (y.load (memory_order_relaxed) == 10)
assert (x.load(memory_order_relaxed) == 10) /* assert B */
对我来说断言 B 永远不会失败,因为 x 必须是 10 并且 y=10 因为线程 2 已经以此为条件。
但是网站上说这个例子中的任何一个断言实际上都可能失败。
最佳答案
To me assert B should never fail, since x must be 10 and y=10 because of thread 2 has conditioned on this.
实际上,您的论点是因为在线程 2 中将 10 存储到 x
发生在将 10 存储到 y
之前,因此在线程 3 中必须是情况。
但是,由于您仅使用宽松的内存操作,因此代码中没有任何内容需要两个不同的线程就不同 变量的修改之间的顺序达成一致。因此,实际上线程 2 可能会先将 10 存储到 x
,然后再将 10 存储到 y
,而线程 3 会以相反的顺序看到这两个操作。
为了确保断言 B 成功,您实际上需要确保当线程 3 看到 y
的值 10 时,它还会看到该线程执行的任何其他副作用在存储时间之前将 10 存储到 y
中。也就是说,您需要将 10 存储到 y
中以同步 从 y
加载 10。这可以通过让存储执行释放并让负载执行获取来完成:
// thread 2
y.store (10, memory_order_release);
// thread 3
if (y.load (memory_order_acquire) == 10)
释放操作与读取存储值的获取操作同步。现在因为线程 2 中的存储与线程 3 中的加载同步,线程 3 中加载之后发生的任何事情都会看到线程 2 中存储之前发生的任何事情的副作用。因此断言将成功。
当然,我们还需要确保断言A成功,方法是让线程1中的x.store
使用release,线程2中的x.load
使用获取。
关于c++ - 对原子类 : memory_order_relaxed 感到困惑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46065770/
给定: std::atomic x; uint64_t f() { x.store(20, std::memory_order::memory_order_relaxed); x.st
在 ThreadMethodOne 中加载时放宽变量 valA 和 valB 同步的最正确方法是什么(假设不存在 valA 和 valB 的虚假高速缓存行共享)?似乎我不应该将 ThreadMetho
假设线程 1 正在对变量 v 进行原子存储使用 memory_order_release (或任何其他顺序)并且线程 2 正在对 v 执行原子读取使用 memory_order_relaxed . 在
Stackoverflow 上已经有一些问题本质上是关于 memory_order_relaxed 的用例,例如: Understanding memory_order_relaxed What ar
C++ 内存模型放宽了原子性,不对内存操作提供任何顺序保证。除了我在这里找到的 C 中的邮箱示例: http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1
Cppreference 给出 following example关于memory_order_relaxed: Atomic operations tagged memory_order_relax
读取 atomic_uint 的值有什么区别?使用 memory_order_relaxed,并读取 volatile unsigned int 的值(假设 volatile 操作是原子的)? 具体来
我试图了解 memory_order_relaxed 的细节。我指的是这个链接:CPP Reference . #include #include std::atomic ptr {nullptr
考虑以下摘自 Herb Sutter 关于原子的演讲的代码片段: smart_ptr 类包含一个名为 control_block_ptr 的 pimpl 对象,其中包含引用计数 refs。 // Th
我在看 this article来自 GCC Wiki 关于 C++ 内存屏障(及其很棒的)。 在我到达这一点之前,它非常简单: 相反的方法是 std::memory_order_relaxed。该模
据我所知,memory_order_relaxed 是为了避免昂贵的内存栅栏,这可能需要在特定架构上进行更多约束排序。在那种情况下,如何在流行的处理器上实现原子变量的总修改顺序? 编辑: atomic
下面是否保证打印 1 后跟 2? auto&& atomic = std::atomic{0}; std::atomic* pointer = nullptr; // thread 1 auto&&
我有一个写入原子变量的线程。 (使用 memory_order_release)。 线程 A 还有许多其他线程读取该变量。 (使用 memory_order_acquire)。 线程 B。 在线程 A
关于内存顺序的 cppreference 文档说 Typical use for relaxed memory ordering is incrementing counters, such as t
我正在研究这个网站:https://gcc.gnu.org/wiki/Atomic/GCCMM/AtomicSync ,这对理解关于原子类的话题非常有帮助。 但是这个放松模式的例子很难理解:
假设我有一个线程 A 写入 atomic_int x = 0;,使用 x.store(1, std::memory_order_relaxed);。如果没有任何其他同步方法,使用 x.load(std
在以下代码中使用 std::memory_order_relaxed 是否正确? #include #include #include #include using namespace std
我正在研究 C++ 内存序列,但它很困惑。 例如: void sumUp(std::atomic& sum, std::vector& val) { int tmpSum = 0; for
C++ 标准规定,原子上的 RMW(读-修改-写)操作将对原子变量的最新值进行操作。因此,当从多个线程并发执行时,对这些操作使用 memory_order_relaxed 不会影响 RMW 操作。 我
std::atomic cnt = {2}; thread 1: doFoo(); if (cnt.fetch_sub(1, std::memory_order_relaxed) ==
我是一名优秀的程序员,十分优秀!