在windows平台上, 线程的挂起可以使用API SuspendThread()函数,而减少线程的挂起计数则可以使用ResumeThread()函数,但是今天却发现了其中隐藏的问题:
1. 现有一个主线程和子线程A,在主线程中调用SuspengThread()使得A被挂起;
2. 主线程中调用ResumeThread()使得A恢复运行;
3. 主线程立刻调用SuspendThread()意图挂起A时,主线程竟然被阻塞在了调用处!也就是说产生了deadlock!
初步的分析如下:
1. 线程A并没有等待的事件,也没有做挂起自身之类的操作,仅仅是循环打印:
for(;;)
{
printf("threadA got running.");
Sleep(300);
}
2. 主线程执行这样的行为:
CreateThread(NULL, ThreadAProc, NULL, &dwThreadIdA);
Sleep(500); // 等待子线程A启动
for(;;)
{
printf("suspend\n");
SuspendThread(hThreadA); // 挂起线程A,此处中主线程会被阻塞
Sleep(200);
printf("resume\n");
ResumeThread(hThreadA); // 使线程A回复运行
}
我的猜测是这样的:SuspendThread()和ResumeThread()是异步的系统调用,即应用层发起调用后,只是简单的发起调用请求,然后直接返回, 内核会在一个不确定的时间后真正的执行该请求,这就极可能导致先发起的调用请求反而后执行,例如SuspendThread()和ResumeThread(),于是导致线程死锁。
希望高手不吝赐教啊