C++11 thread lock 死鎖解決方法

#include <iostream>
#include <mutex>
#include <thread>


using namespace std;


class Account{

public:
    //when create is always true
    Account(const std::string& acountName)
    {
        std::lock_guard<std::mutex> m_lock(m_mutex);
        m_accountName = acountName;
        m_Money = 0;
    }

    //transfer Money


public:
    string  m_accountName;
    int     m_Money;
    std::mutex  m_mutex;
};

void old_transferNow(Account& sender,Account& receiver)
{
    //爲解決死鎖問題,一個通用的解決辦法是採用順序鎖,這也是C++11以前所採用的的
    if(&sender.m_mutex < &receiver.m_mutex)
    {
        std::lock_guard<std::mutex> Lock1(receiver.m_mutex);
        std::lock_guard<std::mutex> Lock2(sender.m_mutex);
        sender.m_Money -= 10;
        receiver.m_Money += 10;

    } else {
        std::lock_guard<std::mutex> Lock1(sender.m_mutex);
        std::lock_guard<std::mutex> Lock2(receiver.m_mutex);
        sender.m_Money -= 10;
        receiver.m_Money += 10;
    }
    cout << "sneder Account: " << sender.m_accountName << endl;
    cout << "sneder Money: " << sender.m_Money << endl;
    cout << "receiver Account: " << sender.m_accountName << endl;
    cout << "receiver Money: " << sender.m_Money << endl;
}

//c++11的新的鎖機制
void transferNow(Account& sender,Account& receiver)
{
    //Lock all
    //把所有的互斥量都按照某種順序鎖起來(可以按照舊的順序鎖的規則)
    std::lock(sender.m_mutex,receiver.m_mutex);
    //注意第二個參數,可參考 https://www.cnblogs.com/haippy/p/3237213.html
    std::lock_guard<std::mutex> senderLock(sender.m_mutex, std::adopt_lock);
    std::lock_guard<std::mutex> receiverLock(receiver.m_mutex, std::adopt_lock);
    sender.m_Money -= 10;
    receiver.m_Money += 10;
    cout << "sneder Account: " << sender.m_accountName << endl;
    cout << "sneder Money: " << sender.m_Money << endl;
    cout << "receiver Account: " << sender.m_accountName << endl;
    cout << "receiver Money: " << sender.m_Money << endl;
}


int main()
{
    Account a("AccountA");
    Account b("AccountB");

    std::thread t1(transferNow, std::ref(a), std::ref(b));
    std::thread t2(transferNow, std::ref(b), std::ref(a));

    t1.join();
    t2.join();

    return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章