1. 程式人生 > >Win32多執行緒之死鎖(DeadLock)

Win32多執行緒之死鎖(DeadLock)

為每一個連結串列(linked list)準備一個critical section之後(關於連結串列,請參看”“,我卻開始了另一個問題。請看下面這個用來交換兩個連結串列內容的函式:

void SwapLists(List  *listA, List * listB)

{

     List   *tmp_list;

     EnterCriticalSection(listA->critical_sec);

      EnterCriticalSection(listB->critical_sec);

      tmp->list = listA->head;

      listA->head  = listB->head;

      listB->head  = temp->list;

      LeaveCriticalSection(listA->critical_sec);

      LeaveCriticalSection(listB->critical_sec);

}

看出問題了嗎?假設下面兩次呼叫發生在不同執行緒的同一個時間點,

執行緒A       SwapLists(home_address_list, work_address_list);

執行緒B       SwapLists(work_address_list, home_address_list);

而線上程A的SwapLists()的第一次EnterCriticalSection()之後,發生了上下文切換(也就是排程程式選換了一個執行緒),然後執行緒B執行了它的SwapLists()操作,兩個執行緒於是會落入”我等你,你等我“的輪迴,執行緒A需要work_address_list,執行緒B需要home_address_list,而雙方都掌握有對方所要的東西。這種情況成為死鎖(deadlock),或成為死亡擁抱(The Deadlly Embrace)。

      任何時候當一段程式碼需要兩個貨更多資源時,都有潛在性的死鎖陰影。死鎖的情況可能非常複雜,許多執行緒的獨立性彼此糾纏在一起,雖然有一些演算法可以偵測並仲裁死鎖狀態,基本上它們仍過於複雜。對大部分程式而言,最好的政策就是找出一種方法以確保死鎖不會發生。稍後你會看到,強迫將資源鎖定,使他們成為”all-or-nothing“(要麼統統獲得,要麼統統沒有),可以阻止死鎖的發生。