中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

C++11怎么實現無鎖隊列

發布時間:2021-08-12 09:25:59 來源:億速云 閱讀:280 作者:chen 欄目:開發技術

這篇文章主要講解了“C++11怎么實現無鎖隊列”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“C++11怎么實現無鎖隊列”吧!

無鎖操作的本質依賴的原子操作,C++11提供了atomic的原子操作支持

atomic

compare_exchange_weak / compare_exchange_strong
當前值與期望值相等時,修改當前值為設定值,返回true
當前值與期望值不等時,將期望值修改為當前值,返回false

memory_order枚舉值

C++11怎么實現無鎖隊列

template<typename T>
class lock_free_stack
{
private:
    struct node
    {
        T data;
        node* next;
        node(T const& data_):
        data(data_)
        {
        }
    };

    std::atomic<node*> head;

public:
    void push(T const& data)
    {
        node* const new_node=new node(data);
        new_node->next=head.load();  

        /*
        ** 當前值.compare_exchange_weak(期望值, 設置值)
        ** 單線程的情況:
        ** 第一次執行while循環:
        ** 此時當前值與期望值相等,修改當前值為設定值 head = new_node,返回true
        ** 多線程的情況:
        ** 第一次執行循環體的時候:
        ** compare_exchange_weak如果失敗, 返回false, 證明有其他線程更新了棧頂head,
        ** 當前值與期望值不等時,將期望值修改為當前值, 即new_node->next等于新的棧頂head,
        ** 被其他線程更新的新棧頂值會被更新到new_node->next中,
        ** 因此循環可以直接再次嘗試壓棧而無需由程序員更新new_node->next。
        ** 然后第二次執行循環體:
        ** 此時 head == new_node->next, 所以 head = new_node.
        ** 如果這是仍有其他線程干擾,則仍為循環更新new_node->next
        */
        while(!head.compare_exchange_weak(new_node->next,new_node));
    }
};

CAS原子操作

  • CAS即Compare and Swap,是所有CPU指令都支持CAS的原子操作(X86中CMPXCHG匯編指令),用于實現實現各種無鎖(lock free)數據結構。

  • CAS用于檢查一個內存位置是否包含預期值,如果包含,則把新值復賦值到內存位置。成功返回true,失敗返回false。

示例代碼如下:

bool compare_and_swap ( int *memory_location, int expected_value, int new_value)
{
    if (*memory_location == expected_value)
    {
        *memory_location = new_value;
        return true;
    }
    return false;
}

ABA問題

所謂ABA(見維基百科的ABA詞條),問題基本是這個樣子:

  • 進程P1在共享變量中讀到值為A

  • P1被搶占了,進程P2執行

  • P2把共享變量里的值從A改成了B,再改回到A,此時被P1搶占。

  • P1回來看到共享變量里的值沒有被改變,于是繼續執行。

雖然P1以為變量值沒有改變,繼續執行了,但是這個會引發一些潛在的問題。ABA問題最容易發生在lock free 的算法中的,CAS首當其沖,因為CAS判斷的是指針的地址。如果這個地址被重用了呢,問題就很大了。(地址被重用是很經常發生的,一個內存分配后釋放了,再分配,很有可能還是原來的地址)

eg:
好比你拿著一個裝滿錢的手提箱在飛機場,此時過來了一個火辣性感的美女,然后她很暖昧地挑逗著你,并趁你不注意的時候,把用一個一模一樣的手提箱和你那裝滿錢的箱子調了個包,然后就離開了,你看到你的手提箱還在那,于是就提著手提箱去趕飛機去了。

這就是ABA的問題。

Fetch-And-Add (FAA)

一般用來對變量做+1的原子操作

Test-And-Set (TAS)

寫值到某個內存位置并傳回其舊值

感謝各位的閱讀,以上就是“C++11怎么實現無鎖隊列”的內容了,經過本文的學習后,相信大家對C++11怎么實現無鎖隊列這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

凤凰县| 阜康市| 湘潭市| 恩施市| 沙坪坝区| 云和县| 葫芦岛市| 会宁县| 萨迦县| 瑞昌市| 宾川县| 铁岭县| 会昌县| 饶平县| 杂多县| 台南县| 鄂伦春自治旗| 定西市| 卓尼县| 页游| 景泰县| 冕宁县| 沅陵县| 宁德市| 宝应县| 乐东| 衡南县| 黑河市| 离岛区| 增城市| 清河县| 六枝特区| 南阳市| 镇雄县| 旺苍县| 嵊泗县| 沅陵县| 澄江县| 阿拉善盟| 玉山县| 罗甸县|