簡體   English   中英

這個鎖的記憶障礙是否正確?

[英]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_acquiretest_and_setmemory_order_releaseclear是不夠的,但我也不確定。

總的來說這是正確的。 由於您在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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM