wince多线程上使用FindWindow可能导致死锁

本文通过一个具体的示例,展示了在MFC程序中如何因不当使用FindWindow函数而导致死锁现象的发生,并深入分析了其背后的原理。文章还提供了一段测试代码,帮助读者理解并避免此类问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

今天同事问我这个事情,我原本也不大相信的后来测试发现果真存在这个问题,PC上不存在的,测试代码如下:


DWORD WINAPI TestThreadProc(void * pParam) // 查找Window句柄线程
{
printf("\nStart:%s\n", __FUNCTION__);


FindWindow(NULL, L"asdasdqwejqwe");


printf("\nEnd:%s\n", __FUNCTION__);

return 0;
}


void CErrorReportDialogDlg::OnBnClickedButton1()   // MFC 按钮事件响应函数

{
// TODO: 在此添加控件通知处理程序代码
CloseHandle(CreateThread(NULL, 0, TestThreadProc, NULL, 0, 0));

for (int i = 0; i < 10; i++)
{
Sleep(1000);

printf("Sleep %d\n", i);
}

}


//执行完成后的打印

Start:TestThreadProc


Sleep 0
Sleep 1
Sleep 2
Sleep 3
Sleep 4
Sleep 5
Sleep 6
Sleep 7
Sleep 8
Sleep 9

End:TestThreadProc


结果证明在非消息线程(窗口线程)调用FindWindow函数时,MFC内部可能是直接调用SendMessage方式到窗口主线程完成Find操作的,那么刚才的事件响应代码还未返回SendMessage自然就会等待函数返回后才执行,所以出现上述打印结果。


那么我们在开发程序时如果用到锁了,那么这个问题严重时就会出现死锁的情况,死锁测试代码如下:

DWORD WINAPI TestThreadProc(void * pParam) // 查找Window句柄线程
{
EnterCriticalSection(&lock);  // 同步处理某些事情

        DoSometings();

FindWindow(NULL, L"asdasdqwejqwe");

LeaveCriticalSection(&lock);

return 0;
}


void CErrorReportDialogDlg::OnBnClickedButton1()   // MFC 按钮事件响应函数

{
// TODO: 在此添加控件通知处理程序代码
CloseHandle(CreateThread(NULL, 0, TestThreadProc, NULL, 0, 0));

EnterCriticalSection(&lock);    // 同步处理某些事情

        DoSometings();   

        LeaveCriticalSection(&lock);

}


这种情况一般来说是应该避免的,也就是一般只锁数据操作,但是往往开发中某些函数被多次封装后,就没那么明显了,这个问题也是隐藏的比较深的。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值