解释:在多线程的环境下,cpu一次只能执行一个线程,所以会涉及到线程切换,如果存在调用全局变量的情况下,就有可能存在线程安全问题,所以说在线程切换时,cpu首先获取令牌,然后才能够继续执行线程,那么线程卡死就是两个线程同时获取和等待令牌,比如存在两个令牌A和B,当某一个线程要使用两个全局变量的时候要同时获取两个令牌 如果这时线程A获取A令牌,那么他还B令牌才能完整执行程序,那么他会一直等待获取B令牌,B线程同样的道理获取了B令牌,但是还差A令牌才能完整运行,这个时候他也会一直等着获取A令牌,这种情况就造成了临界区的卡死。
实现代码如下:
#include <windows.h>
#include<stdio.h>
CRITICAL_SECTION cs;
CRITICAL_SECTION cs1;
int x = 2;
int y = 3;
DWORD WINAPI ThreadProc1(LPVOID lpParameter)
{
EnterCriticalSection(&cs);
x = x + 1;
printf("%d\n", x);
if (x > 0) {
EnterCriticalSection(&cs1);
y = y + 1;
printf("%d\n", y);
LeaveCriticalSection(&cs1);
}
LeaveCriticalSection(&cs);
return 0;
}
DWORD WINAPI ThreadProc2(LPVOID lpParameter)
{
EnterCriticalSection(&cs1);
x = x + 1;
printf("%d\n", x);
if (x > 0) {
EnterCriticalSection(&cs);
y = y + 1;
printf("%d\n", y);
LeaveCriticalSection(&cs);
}
LeaveCriticalSection(&cs1);
return 0;
}
int main(int argc, char* argv[])
{
InitializeCriticalSection(&cs);
//printf("主线程:%x %x %x\n",cs.LockCount,cs.RecursionCount,cs.OwningThread);
//创建一个新的线程
HANDLE hThread1 = CreateThread(NULL, 0, ThreadProc1,
NULL, 0, NULL);
//创建一个新的线程
HANDLE hThread2 = CreateThread(NULL, 0, ThreadProc2,
NULL, 0, NULL);
//如果不在其他的地方引用它 关闭句柄
CloseHandle(hThread1);
CloseHandle(hThread2);
Sleep(1000 * 60 * 60);
return 0;
}