数据毁坏或一个死锁几乎是一个多线程应用中发生的最坏的问题,它具有非常恶毒的和敏感的形式但相当困难重新或者被跟踪。由于这种原因,强烈推荐你在这些情况发生之前分析你的多线程应用程序可能的死锁条件并检查和删除这些死锁。
非常简单一个死锁两个或多个线程彼此等待对方释放共享资源而不释放它占有的资源。因为所有参与死锁的线程被挂起并且因此而不能释放它们占有的资源,没有线程可以继续运行,并且整个应用程序(或者更坏的,多个共享资源的应用程序)看起来被吊死了。
下面是一个很简单的多线程应用程序,我叫他GOOFY(傻瓜),方便我们后来容易引用,我们在后面经常提及它。
#include <windows.h>
#include <stdio.h>
CRITICAL_SECTION cs1,cs2;
long WINAPI ThreadFn(long);
main ()
{
long iThreadID;
InitializeCriticalSection (&cs1);
InitializeCriticalSection (&cs2);
CloseHandle(CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)ThreadFn,
NULL,0,&iThreadID));
while(TRUE)
{
EnterCriticalSection(&cs1);
printf("\nThread1 has entered Critical Section 1 but not 2.");
EnterCriticalSection(&cs2);
printf("\nThread1 has entered Critical Section 1 and 2!");
LeaveCriticalSection(&cs2);
printf("\nThread1 has left Critical Section 2 but still owns 1.");
LeaveCriticalSection(&cs1);
printf("\nThread1 has left both critical sections...");
Sleep(20);
};
return(0);
}
long WINAPI ThreadFn(long lParam)
{
while(TRUE)
{EnterCriticalSection(&cs2);
printf("\nThread2 has entered Critical Section 2 but not 1.");
EnterCriticalSection(&cs1);
printf("\nThread2 has entered Critical Section 2 and 1!");
LeaveCriticalSection(&cs1);
printf("\nThread2 has left Critical Section 1 but still owns 2.");
LeaveCriticalSection(&cs2);
printf("\nThread2 has left both critical sections...");
Sleep(20);
};
}
你可以将GOOFY代码COPY到一个C源文件中,然后编译和连接它,然后运行,你会看到GOOFY运行了一段时间之后会挂起。线程1声明了关键段1并且被挂起,因为其等待关键段2,然而线程2拥有关键段2并等待线程释放关键段1,而这种情况从不会出现,当然因为线程1在线程释放关键段之前不会释放关键段1,当然,因为。。。(重复)
不幸的是,死锁并不是总是这么容易被发现。在一个复杂应用程序,几个相互依赖的条件