[英]Are the memory barriers correct for this lock?
它是否正確? 我是否正確假設在std::atomic_flag
上應用內存排序不提供通用鎖的同步?
#include <atomic>
class Spinlock
{
public:
Spinlock(): f(ATOMIC_FLAG_INIT) {}
void lock()
{
while(f.test_and_set(std::memory_order_relaxed));
std::atomic_thread_fence(std::memory_order_acquire);
}
void unlock()
{
std::atomic_thread_fence(std::memory_order_release);
f.clear(std::memory_order_relaxed);
}
private:
std::atomic_flag f;
};
我很抱歉,如果這是一個愚蠢的問題,但我覺得一個std::atmoic_thread_fence
是必要的通用鎖,這將memory_order_acquire
在test_and_set
和memory_order_release
上clear
是不夠的,但我也不確定。
總的來說這是正確的。 由於您在test_and_set函數中使用了'std :: memory_order_relaxed',因此在沒有'atomic_thread_fence'調用的情況下,沒有任何東西會阻止在Mutex :: lock之前和之后完成的操作的重新排序。 由於預期'Mutex :: lock'充當內存屏障,因此需要調用'atomic_thread_fence'。 但我相信通過在'test_and_set函數'中使用'std :: memory_order_acquire'可以實現相同的效果。 請參閱: http : //en.cppreference.com/w/cpp/atomic/atomic_flag
通常的模式是使用test_and_set(memory_order_acquire)
和clear(memory_order_release)
。 但我懷疑你已經知道了。
根據標准第29.8節[atomic.fences](2):
如果存在原子操作X和Y,則釋放柵欄A與獲取柵欄B同步,兩者都在一些原子對象M上操作,使得A在X之前被排序,X修改M,Y在B之前被排序,並且Y讀取值如果是釋放操作,則由X寫入或由假設釋放序列中的任何副作用寫入的值X將結束。
在你的代碼中,A是你的unlock()
函數中的圍欄; X是clear()
; Y是lock()
函數中的fence; B是test_and_set()
。 因此,您的代碼符合本部分標准的要求,因此您的unlock()
和lock()
函數已正確同步。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.