一、死鎖會在什麼情況發生
1、假設有如下代碼
mutex; //代表一個全局互斥對象
void A()
{
mutex.lock();
//這裏操作共享數據
B(); //這裏調用B方法
mutex.unlock();
return;
}
void B()
{
mutex.lock();
//這裏操作共享數據
mutex.unlock();
return;
}
此時會由於在A、B方法中相互等待unlock而導致死鎖。
2、假設有如何代碼
mutex; //代表一個全局互斥對象
void A()
{
mutex.lock();
//這裏操作共享數據
if(.....)
{
return;
}
mutex.unlock();
return;
}
由於在if的執行體內直接retun,而沒有調用unlock,導致另一個線程再調用A方法就出現死鎖。
二、另一個總結
不管什麼原因,死鎖的危機都是存在的。那麼,通常出現的死鎖都有哪些呢?我們可以一個一個看過來,
(1)忘記釋放鎖
- void data_process()
- {
- EnterCriticalSection();
- if(/* error happens */)
- return;
- LeaveCriticalSection();
- }
- void sub_func()
- {
- EnterCriticalSection();
- do_something();
- LeaveCriticalSection();
- }
- void data_process()
- {
- EnterCriticalSection();
- sub_func();
- LeaveCriticalSection();
- }
- void data_process1()
- {
- EnterCriticalSection(&cs1);
- EnterCriticalSection(&cs2);
- do_something1();
- LeaveCriticalSection(&cs2);
- LeaveCriticalSection(&cs1);
- }
- void data_process2()
- {
- EnterCriticalSection(&cs2);
- EnterCriticalSection(&cs1);
- do_something2();
- LeaveCriticalSection(&cs1);
- LeaveCriticalSection(&cs2);
- }
- /*
- * A - B
- * | |
- * C - D
- */
假設有A、B、C、D四個人在一起吃飯,每個人左右各有一隻筷子。所以,這其中要是有一個人想吃飯,他必須首先拿起左邊的筷子,再拿起右邊的筷子。現在,我們讓所有的人同時開始吃飯。那麼就很有可能出現這種情況。每個人都拿起了左邊的筷子,或者每個人都拿起了右邊的筷子,爲了吃飯,他們現在都在等另外一隻筷子。此時每個人都想吃飯,同時每個人都不想放棄自己已經得到的一那隻筷子。所以,事實上大家都吃不了飯。
總結:
(1)死鎖的危險始終存在,但是我們應該儘量減少這種危害存在的範圍
(2)解決死鎖花費的代價是異常高昂的
(3)最好的死鎖處理方法就是在編寫程序的時候儘可能檢測到死鎖
(4)多線程是一把雙刃劍,有了效率的提高當然就有死鎖的危險
(5)某些程序的死鎖是可以容忍的,大不了重啓機器,但是有些程序不行