死锁

来源:互联网 发布:低价入手已备案域名 编辑:程序博客网 时间:2024/06/03 07:44
ormal; font-weight: normal; letter-spavoid SwapLists(List *list, List *list2)
{
List *tmp_list;
EnterCriticalSection(list1->critical_sec);
EnterCriticalSection(list2->critical_sec);
tmp->list = list1->head;
list1->head = list2->head;
list2->head = temp->list;
LeaveCriticalSection(list1->critical_sec);
LeaveCriticalSection(list2->critical_sec);
}
假设下面两次调用发生在不同线程的同一个时间点:
线程ASwapLists(home_address_list, work_address_list);
线程BSwapLists(work_address_list, home_address_list);//注意实参的顺序,这是死锁的关键。

而在线程A的SwapLists()的第一次EnterCriticalSection() 之后,发生了context switch(译注:也就是调度程序选换了一个线程),然后线程B执行了它的SwapLists()操作,两个线程于是会落入“我等你,你等我”的轮回。线程A需要work_address_list,线程B需要hom e_address_list,而双方都掌握有对方所要的东西。这种情况称为死锁(deadlock)。


home_address_list, work_address_list这两个实参,肯定是作为共享数据的。

线程A和线程B中,都调用方法SwapLists()去读取这两个list。


解释:

线程A进入EnterCriticalSection(list1->critical_sec);之后,获取了home_address_list的锁。此时,上下文切换,线程A失去cpu时间片。

线程B得到cpu时间片,开始执行。线程B进入EnterCriticalSection(list1->critical_sec);之后,获取了work_address_list的时间片。

此时,死锁发生。


上下文切换是肯定会发生的。当在一个单核cpu上,同时运行两个线程的时候,上述情况就会发生。




死锁的解决方法:

任何时候当一段代码需要两个(或更多)资源时,都有潜在性的死锁阴影。
死锁的情况可能非常复杂,许多线程的独立性彼此纠缠在一起。虽然有一些算法可以侦测并仲裁死锁状态, 基本上它们仍嫌过于复杂。对大部分程序而言,最好的政策就是找出一种方法以确保死锁不会发生。稍后你会看到,强迫将资源锁定,使它们成为" all-or-nothing"(要不统统获得,要不统统没有),可以阻止死锁的发生。


实际上我们是使用WaitForMultipleObjects()来等待两支筷子。如果只有一支筷子可用,不算是取得一“双”筷子(WaitForMultipleObjects()也因此不会返回)。程序代码像这样:
WaitForMultipleObjects(2, myChopsticks, TRUE, INFINITE);

这个函数的参数告诉我们,myChopsticks数组中有两个handles是等待目标。当其中每一个handle都处于激发状态时,该函数才会返回

0 0