首頁  >  文章  >  後端開發  >  C++ 並發程式設計中死鎖及避免死鎖的策略?

C++ 並發程式設計中死鎖及避免死鎖的策略?

WBOY
WBOY原創
2024-06-02 10:44:57649瀏覽

死鎖發生於執行緒因等待其他執行緒釋放資源而陷入環形等待狀態。避免死鎖的策略有:避免循環等待有序使用資源超時策略在哲學家進餐問題中,有序使用筷子資源(左筷子在前)解決了死鎖問題。

C++ 并发编程中死锁及避免死锁的策略?

C++ 並發程式設計中的死鎖及避免死鎖的策略

什麼是死鎖?

在並發程式設計中,死鎖發生當多個執行緒同時等待其他執行緒釋放資源時。這會導致執行緒無限期地阻塞,無法繼續執行。

避免死鎖的策略

避免死鎖有以下幾種策略:

  • ##避免循環等待:確保執行緒不會因為等待其他執行緒釋放資源而形成環形等待關係。
  • 有順序使用資源:為所有資源建立一個固定的取得順序,並強制所有執行緒依照此順序取得資源。
  • 逾時策略:為取得資源設定逾時時間,當執行緒在逾時時間內無法取得資源時,即釋放資源。

實戰案例:哲學家進餐問題

哲學家進餐問題是一個經典的死鎖問題。有 5 個哲學家圍坐在一張圓桌旁,每人有一根筷子。他們可以隨時拿取左右兩根筷子進餐,但只能同時拿取一根筷子。如果所有哲學家同時拿起左邊的筷子,那麼他們都會陷入死鎖狀態。

我們可以使用

有序使用資源策略來解決此問題:

// 筷子类
class Chopstick {
public:
    Chopstick() {
        m_mutex = new std::mutex;
    }

    ~Chopstick() {
        delete m_mutex;
    }

    void lock() {
        m_mutex->lock();
    }

    void unlock() {
        m_mutex->unlock();
    }

private:
    std::mutex* m_mutex;
};

// 哲学家类
class Philosopher {
public:
    Philosopher(int id, Chopstick* left, Chopstick* right)
        : m_id(id), m_left(left), m_right(right) {}

    void dine() {
        while (true) {
            // 获取左边的筷子
            m_left->lock();

            // 获取右边的筷子
            m_right->lock();

            // 进餐
            std::cout << "哲学家 " << m_id << " 正在进餐" << std::endl;

            // 放下右边的筷子
            m_right->unlock();

            // 放下左边的筷子
            m_left->unlock();
        }
    }

private:
    int m_id;
    Chopstick* m_left;
    Chopstick* m_right;
};

int main() {
    // 创建 5 根筷子
    Chopstick chopsticks[5];

    // 创建 5 个哲学家
    Philosopher philosophers[5] = {
        Philosopher(0, &chopsticks[0], &chopsticks[4]),
        Philosopher(1, &chopsticks[1], &chopsticks[0]),
        Philosopher(2, &chopsticks[2], &chopsticks[1]),
        Philosopher(3, &chopsticks[3], &chopsticks[2]),
        Philosopher(4, &chopsticks[4], &chopsticks[3])
    };

    // 启动哲学家线程
    std::thread threads[5]; 
    for (int i = 0; i < 5; i++) {
        threads[i] = std::thread(&Philosopher::dine, &philosophers[i]);
    }

    // 等待哲学家线程结束
    for (int i = 0; i < 5; i++) {
        threads[i].join();
    }

    return 0;
}

在這個例子中,我們為每一個筷子創建了一個

std: :mutex互斥鎖,確保一次只能有一個哲學家取得該筷子。透過依序取得筷子,我們避免了死鎖的發生。

以上是C++ 並發程式設計中死鎖及避免死鎖的策略?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

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