Phi*_*ppe 0 c++ atomic memory-model stdatomic
我在几个地方读到,宽松的排序可以生成唯一的 ID。我对此表示怀疑,因为如果两个线程同时调用:
uniqueId.fetch_add(1, std::memory_order::relaxed);
那么线程 A 递增的值可能对线程 B 不可见。这意味着,两个线程可以获得相同的唯一 ID。
出于这个原因,我宁愿使用std::memory_order::acq_rel
你怎么认为?
在实践中无法测试。
std::memory_order_*是关于如何同步存储和加载到原子对象本身以外的内存位置。
单个原子对象的值在所有线程中始终保持一致。它具有所有线程都同意的一个修改顺序,并且与每个线程中加载/存储的顺序一致,无论std::memory_order_*.
(但是,这仅适用于单独查看的每个原子对象。这不适用于多个原子对象之间。)
在您的情况下是否std::memory_order::relaxed足够取决于生成的 ID 值是否将通过线程之间的其他共享对象(无论是否原子)使用,但是表达式
uniqueId.fetch_add(1, std::memory_order::relaxed)
Run Code Online (Sandbox Code Playgroud)
,即使在多个线程中使用时,每个 ID 也只会生成一次(假设uniqueId引用同一个std::atomic对象,没有其他存储应用于它,并且不会发生溢出/环绕)。但重要的是,它fetch_add本身就是一个原子的读-修改-写。加载后跟存储不会是原子操作,并且不能保证来自另一个线程的存储不会介入加载和存储之间。