记忆障碍,不确定我是否可以放松?

时间:2022-11-17 18:02:50

Using pseudo code I have two threads both trying to reach and "pop" the same data first:

使用伪代码我有两个线程都试图到达并首先“弹出”相同的数据:

Thread1

线程1

DataBlock db = memoryLocationX.reserveBlock();

Thread2

线程2

DataBlock anotherDB = memoryLocationX.reserveBlock();

and reserveBlock() performs an std::exchange() on the memory, returning the original value and replacing it with a blank value, so only one thread can obtain the data:

和reserveBlock()在内存上执行std :: exchange(),返回原始值并将其替换为空值,因此只有一个线程可以获取数据:

DataBlock reserveBlock(){
    return DataBlock(_internalState.exchange(EMPTY_VALUE));
}

My question is, under what circumstances can I use std::memory_order_relaxed as second argument to exchange()? All I am trying to ensure is that only one of the threads retrieves the data stored within _internalState. But this is achieved already with exchange(), so does this mean I can use std::memory_order_relaxed?

我的问题是,在什么情况下我可以使用std :: memory_order_relaxed作为exchange()的第二个参数?我想要确保的是,只有一个线程检索_internalState中存储的数据。但这已经通过exchange()实现了,所以这是否意味着我可以使用std :: memory_order_relaxed?

1 个解决方案

#1


2  

With std::memory_order_relaxed you get no guarantees, only that there will be no data races. It avoids undefined behaviour but there are few situations where it is really useful (e.g., if you can guarantee synchronization by other ways).

使用std :: memory_order_relaxed,你得不到保证,只有没有数据竞争。它避免了未定义的行为,但很少有情况下它非常有用(例如,如果您可以通过其他方式保证同步)。

In your example, you need to synchronize between threads, so if you use relaxed semantics, you would still need to synchronize explicitely anyway. Otherwise, it is not guaranteed that the other threads sees the modification.

在您的示例中,您需要在线程之间进行同步,因此如果您使用轻松的语义,您仍然需要明确地同步显示。否则,不保证其他线程看到修改。

In the end, it will most likely not be faster and the code will be more complicated.

最后,它很可能不会更快,代码也会更复杂。

#1


2  

With std::memory_order_relaxed you get no guarantees, only that there will be no data races. It avoids undefined behaviour but there are few situations where it is really useful (e.g., if you can guarantee synchronization by other ways).

使用std :: memory_order_relaxed,你得不到保证,只有没有数据竞争。它避免了未定义的行为,但很少有情况下它非常有用(例如,如果您可以通过其他方式保证同步)。

In your example, you need to synchronize between threads, so if you use relaxed semantics, you would still need to synchronize explicitely anyway. Otherwise, it is not guaranteed that the other threads sees the modification.

在您的示例中,您需要在线程之间进行同步,因此如果您使用轻松的语义,您仍然需要明确地同步显示。否则,不保证其他线程看到修改。

In the end, it will most likely not be faster and the code will be more complicated.

最后,它很可能不会更快,代码也会更复杂。