MFC工作线和UI主线程互锁问题的解决方法
2012-03-01 12:19
190 查看
在以下代码中,线程Thread退出时,可能会要UI线程互锁
究其原因,是因为WaitForSingleObject函数会使线程的释放CPU时间,类似于Sleep的行为,如果此时 Work线程执行到操作UI元素的代码,但此时UI线程事实上已经处于休眠状态,因此操作UI元素的代码要等到UI线程被唤醒才会返回,这样一来,UI线程和Work线程便陷于互相等待的境地,死锁便由此发生。
解决方法:
既然死锁的原因是由于UI线程和Work线程的互相等待,那我们就尽量避免这种情况的发生。在StopRead函数中作如此修改:
在ReadThread函数返回前,加如下代码:
如此改动之后,由UI线程不会陷入长时间休眠,因此Work线程访问UI的代码也不会陷入等待状态,死锁便不会发生。
Delay函数如下:
原链接地址——
http://blog.sina.com.cn/s/blog_5ee42ba30100cbjm.html
void CTagScanPCDlg::StopRead() { if (m_hEvent != NULL) //线程结束等待事件 { SetEvent(m_hEvent); } if (m_hThreadRead != NULL) { WaitForSingleObject(m_hThreadRead,INFINITE); //等待线程结束 DWORD dwExitCode = 0; m_hThreadRead = NULL; } m_hEvent = NULL; } DWORD WINAPI CTagScanPCDlg::ReadThread(LPVOID lpParam) { //…… while (WaitForSingleObject(pDlg->m_hEvent,0) == WAIT_TIMEOUT) { //…… pDlg->SetDlgItemText(IDC_TAGGROUP,(LPCTSTR)szTextTitle); //操作UI元素 //…… } //…… }
究其原因,是因为WaitForSingleObject函数会使线程的释放CPU时间,类似于Sleep的行为,如果此时 Work线程执行到操作UI元素的代码,但此时UI线程事实上已经处于休眠状态,因此操作UI元素的代码要等到UI线程被唤醒才会返回,这样一来,UI线程和Work线程便陷于互相等待的境地,死锁便由此发生。
解决方法:
既然死锁的原因是由于UI线程和Work线程的互相等待,那我们就尽量避免这种情况的发生。在StopRead函数中作如此修改:
if (m_hEvent != NULL) //线程结束等待事件 { SetEvent(m_hEvent); Delay(10000,m_hDelayEvent) //Delay为一延时函数,m_hDelayEvent为由CreateEvent创建的事件,创建于Work线程创建之前,当m_hDelayEvent被重置时,Delay函数便会返回 }
在ReadThread函数返回前,加如下代码:
SetEvent(pDlg->m_hDelayEvent); //重置m_hDelayEvent
如此改动之后,由UI线程不会陷入长时间休眠,因此Work线程访问UI的代码也不会陷入等待状态,死锁便不会发生。
Delay函数如下:
void Delay(DWORD dwTime,HANDLE hEvent) { DWORD dwStart = GetTickCount(); if (hEvent != NULL) { while(WaitForSingleObject(hEvent,0) == WAIT_TIMEOUT) { MSG msg; //响应其它消息的处理 while(::PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { ::TranslateMessage(&msg); ::DispatchMessage(&msg); } if(GetTickCount() - dwStart > dwTime) return; ::Sleep(1); } } else while(1) { MSG msg; //响应其它消息的处理 while(::PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { ::TranslateMessage(&msg); ::DispatchMessage(&msg); } if(GetTickCount() - dwStart > dwTime) return; ::Sleep(1); } }
原链接地址——
http://blog.sina.com.cn/s/blog_5ee42ba30100cbjm.html
相关文章推荐
- J2EE开发工作中遇到的异常问题及解决方法总结
- 关于 qt程序退出出现“已停止工作”程序奔溃问题 的解决方法
- MFC一些问题的解决方法
- MFC 界面假死问题解决方法
- VC工作区间就不能正常打开问题解决方法
- MFC工程从VC6.0转换成VS2013遇到的问题以及解决方法
- VS2008运行MFC程序,提示microsoft incremental linker已停止工作解决方法
- QT结合MFC的难点问题解决方法
- 把工作中遇到的问题和解决方法记录下来!
- 使用MFC过程中遇到的问题以及解决方法(二)
- 从MFC的复杂性谈解决问题的方法
- ogre 1.6和mfc 的debug new冲突问题的白痴解决方法。。
- 近期做东西所遇到的几个MFC恼火的问题及解决方法
- 方法:如何解决用MFC实现的ping功能中把目标主机不可到达的当成ping通的问题
- OpenGL+MFC导致闪烁、不刷新等问题的解决方法
- 工作总结--解决问题的方法
- MFC采用MSComm控件通信时,出现error LNK2001:无法解析的外部符号问题的解决方法
- MFC CTreectrl 通过DeleteAllItems删除全部节点后,再插入节点不显示问题解决方法
- 关于安装IE8之后VS2008使用MFC出现问题的解决方法
- 关于MFC中的Debug Assertion Failed问题的一种可能的解决方法。