首頁  >  文章  >  後端開發  >  C++ 多執行緒程式設計中 deadlocks 的成因是什麼?

C++ 多執行緒程式設計中 deadlocks 的成因是什麼?

WBOY
WBOY原創
2024-06-03 10:05:58935瀏覽

在 C++ 多執行緒程式設計中,死鎖的成因主要有:1. 互斥鎖不當使用;2. 順序鎖定。在實戰中,如果多個執行緒同時嘗試取得同一組鎖,依照不同的順序獲取,就可能導致死鎖。可以透過始終按照相同的順序取得鎖來避免這種情況。

C++ 多线程编程中 deadlocks 的成因是什么?

在C++ 多執行緒程式設計中導致死鎖的成因

死鎖是一個並發程式設計中常見的錯誤,它發生在一個或多個執行緒等待另一個執行緒釋放鎖,而另一個執行緒又在等待前者釋放鎖。這會導致程序陷入僵持,無法繼續執行。

在C++ 中,死鎖通常由以下原因引起:

  • #互斥鎖不當使用:如果沒有正確地使用互斥鎖,執行緒可能會嘗試同時取得同一鎖,導致死鎖。
  • 順序鎖定:如果執行緒需要取得多個鎖,它們應該總是按照相同的順序取得這些鎖。否則,可能導致死鎖,因為一個執行緒可能會等待另一個執行緒釋放一個鎖,而另一個執行緒又等待該執行緒釋放另一個鎖。

實戰案例:

考慮以下程式碼:

class BankAccount {
public:
    std::mutex m_mutex; // 互斥锁
    int balance = 0;
};

void transfer(BankAccount &from, BankAccount &to, int amount) {
    std::lock_guard<std::mutex> lock1(from.m_mutex); // 锁定第一个账户
    std::lock_guard<std::mutex> lock2(to.m_mutex); // 锁定第二个账户
    
    // 从第一个账户扣除金额
    from.balance -= amount;
    
    // 将金额添加到第二个账户
    to.balance += amount;
}

在這個例子中,如果兩個執行緒同時呼叫transfer () 函數,而它們試圖將錢從不同的帳戶轉移到同一個帳戶,就會發生死鎖。這是因為一個執行緒會先鎖定第一個帳戶,然後等待另一個執行緒釋放第二個帳戶,而另一個執行緒又會先鎖定第二個帳戶,然後等待第一個執行緒釋放第一個帳戶。

為了避免這種情況,執行緒應該始終按照相同的順序取得鎖,例如:

void transfer(BankAccount &from, BankAccount &to, int amount) {
    // 按照账户 ID 排序账户
    if (from.getId() < to.getId()) {
        std::lock_guard<std::mutex> lock1(from.m_mutex);
        std::lock_guard<std::mutex> lock2(to.m_mutex);
    } else {
        std::lock_guard<std::mutex> lock2(to.m_mutex);
        std::lock_guard<std::mutex> lock1(from.m_mutex);
    }
    
    // 从第一个账户扣除金额
    from.balance -= amount;
    
    // 将金额添加到第二个账户
    to.balance += amount;
}

#透過依照帳戶ID 排序帳戶並按照相同的順序鎖定它們,我們可以防止這種情況發生。

以上是C++ 多執行緒程式設計中 deadlocks 的成因是什麼?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn