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