关闭对话框结束线程 在对话框的OnInitdialog()中创建一个线程,在关闭时置一个变量为TRUE,在线程中检测为TRUE,直接return;在关闭时Waitforsingleobject那个线程,然后就一直堵塞在这了,在线程中设断点也跟踪不到,不知执行到哪吧,高手请指点迷津 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 不要在主线程中Waitforsingleobject,创建一个线程另外监视,这样可以防止主线程堵塞 汗,公司使用虚拟机上网,不能考代码,而且输入法还是紫光的,的打半天。BOOL CdlgOpera::OnInitDialog(){ .... LPVOID lpvoid = this; m_hThread = CreateThread(NULL, 0, ThreadPro, lpvoid, Create_SUSPENDED, 0); ... ResumeThread(m_hThread);.....}void CdlgOpera::OnCancel(){ ... KillTimer(1); bStopNow = TRUE;//结束线程 DWORD dwResult; GetExitCodeThread(m_hThread, &dwResult); if (dwResult != 0) { WaitForSingleObject(m_hThread, INFINITE); //死在这 } CloseHandle(m_hThread); .......}void CdlgOpera::AddToDownLoadList(){...... POSITION pos = fileList.GetTailPosition(); while(pos) { sLine = fileList.GetPrev(pos); i++; TRACE("Stop:%d\n%d\n", i, bStopNow); if(bStopNow) { TRACE("STOP!\n"); return; } ....... } .....}最后可见的调试信息为:Stop:2420就是没有STOP!跟踪也跟不到,迷惑 void CdlgOpera::AddToDownLoadList()这个函数是线程ThreadPro里调用的一个函数 void CdlgOpera::OnCancel() { ... KillTimer(1); bStopNow = TRUE;//结束线程 DWORD dwResult; GetExitCodeThread(m_hThread, &dwResult); if (dwResult != 0) { WaitForSingleObject(m_hThread, INFINITE); //死在这 } CloseHandle(m_hThread); ....... } 里面你用主线程等待子线程,等不到的话就会挂起自己 为什么需要Waitforsingleobject 线程互锁了,常见的原因是:线程中要访问主线程的窗口(或窗口中的控件),因为访问窗口实际上是通过SendMessage由窗口所属线程来处理的,而主线程此时在等待另一个由线程触发的事件(线程结束),而没有取消息,所以线程一直在等待主线程处理消息而不会结束,结果就是两个线程永远等待。建议解决办法:主线程在设置标志通知线程结束之后立即返回,线程在退出前给窗口发送一个自定义消息,主线程响应这个消息关闭窗口(无须等待线程结束)。 可以用事件控制线程退出 线程每次循环一次看这个事件到没有,如果到则线程退出WaitForSingleObject( 事件 ,0); 不要阻塞主线程。Waitforsingleobject在主线程中一定会阻塞主线程。你应该在子线程中Waitforsingleobject()一个事件。当退出的时候,直接把事件置为有信号的状态。这样线程就退出了。也可以在子线程中PeekMessage()当得到WM_QUIT这个消息的时候,就退出来。 俺给个建议:void CdlgOpera::OnCancel() { ... KillTimer(1); bStopNow = TRUE;//结束线程 DWORD dwResult; GetExitCodeThread(m_hThread, &dwResult); if (dwResult != 0) { WaitForSingleObject(m_hThread, INFINITE); //死在这 } CloseHandle(m_hThread); ....... } 可以修改一下: if (dwResult != 0) { while (WaitForSingleObject(m_hThread, 0) != WAIT_OBJECT_0) { MSG msg; //这里增加消息处理函数,让线程还能得到执行的机会 while(::PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE)) { if (!AfxGetThread()->PumpMessage() break; } } } 你可以试下 ThreadPro线程被挂住了,或者没有走到检查那个变量的逻辑上。比如POSITION pos = fileList.GetTailPosition(); 如果pos为空,则不会走到里面检查if(bStopNow)的地方。 问题现象: 在主线程中设置bStopNow标志,WaitForSingleObject(threadHandle, INFINITE); 线程马上就死掉了!!!通过调试信息输出,看到线程可能停止在while循环的任意位置。 问题原因: 因为本程序涉及向ListCtrl控件中添加记录。 我在InsertItem的反汇编中发现了如下的代码 call dword ptr [__imp__SendMessageA@16 (7C141B54h)] 可见,InsertItem是必须借助消息循环来完成任务的。如果我们在主线程中WaitForSingleObject了,必然导致主线程阻塞,也就导致了消息循环的阻塞,最终导致工作线程Crash掉了*_* 总结: 如果在工作线程中有可能涉及到了消息驱动的API,那么不能在主线程中使用WaitForSingleObject一类函数,而必须使用下述的方案:while(TRUE) { DWORD result ; MSG msg ; result = MsgWaitForMultipleObjects(1, &readThreadHandle, FALSE, INFINITE, QS_ALLINPUT); if (result == (WAIT_OBJECT_0)) { break; } else { PeekMessage(&msg, NULL, 0, 0, PM_REMOVE); DispatchMessage(&msg); } } 或者14楼方案。 hook钩子只能用在MFC里吗? 如何让动态创建的菜单第二次运行程序仍然存在 opengl显示图像 请问显式链接dll后怎样使用其中的导出变量?? MYIM即时通信系统 关于VC调用SOAP的问题。 如何固定一个对话框在窗口的位置,不让其拖动呢? 怎么样用C++代码实现FTP或者WEB站点的管理? 想认识与熟悉OPENGL的朋友,MM:[email protected] 小妹有事请教各位!! CPropertySheet上有OK和Cancel两个按钮,请问点击OK后调用的是哪个函数? 为什么我的位图加载后,显示不出来
BOOL CdlgOpera::OnInitDialog()
{
....
LPVOID lpvoid = this;
m_hThread = CreateThread(NULL, 0, ThreadPro, lpvoid, Create_SUSPENDED, 0);
...
ResumeThread(m_hThread);
.....
}void CdlgOpera::OnCancel()
{
...
KillTimer(1);
bStopNow = TRUE;//结束线程
DWORD dwResult;
GetExitCodeThread(m_hThread, &dwResult);
if (dwResult != 0)
{
WaitForSingleObject(m_hThread, INFINITE); //死在这
}
CloseHandle(m_hThread);
.......
}void CdlgOpera::AddToDownLoadList()
{
......
POSITION pos = fileList.GetTailPosition();
while(pos)
{
sLine = fileList.GetPrev(pos);
i++;
TRACE("Stop:%d\n%d\n", i, bStopNow);
if(bStopNow)
{
TRACE("STOP!\n");
return;
}
.......
}
.....
}
最后可见的调试信息为:
Stop:242
0
就是没有STOP!
跟踪也跟不到,迷惑
{
...
KillTimer(1);
bStopNow = TRUE;//结束线程
DWORD dwResult;
GetExitCodeThread(m_hThread, &dwResult);
if (dwResult != 0)
{
WaitForSingleObject(m_hThread, INFINITE); //死在这
}
CloseHandle(m_hThread);
.......
}
里面你用主线程等待子线程,等不到的话就会挂起自己
建议解决办法:主线程在设置标志通知线程结束之后立即返回,线程在退出前给窗口发送一个自定义消息,主线程响应这个消息关闭窗口(无须等待线程结束)。
你应该在子线程中Waitforsingleobject()一个事件。当退出的时候,直接把事件置为有信号的状态。这样线程就退出了。
也可以在子线程中PeekMessage()当得到WM_QUIT这个消息的时候,就退出来。
void CdlgOpera::OnCancel()
{
...
KillTimer(1);
bStopNow = TRUE;//结束线程
DWORD dwResult;
GetExitCodeThread(m_hThread, &dwResult);
if (dwResult != 0)
{
WaitForSingleObject(m_hThread, INFINITE); //死在这
}
CloseHandle(m_hThread);
.......
} 可以修改一下:
if (dwResult != 0)
{
while (WaitForSingleObject(m_hThread, 0) != WAIT_OBJECT_0)
{
MSG msg; //这里增加消息处理函数,让线程还能得到执行的机会
while(::PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE))
{
if (!AfxGetThread()->PumpMessage() break;
}
}
}
你可以试下
在主线程中设置bStopNow标志,WaitForSingleObject(threadHandle, INFINITE);
线程马上就死掉了!!!通过调试信息输出,看到线程可能停止在while循环的任意位置。 问题原因:
因为本程序涉及向ListCtrl控件中添加记录。
我在InsertItem的反汇编中发现了如下的代码
call dword ptr [__imp__SendMessageA@16 (7C141B54h)]
可见,InsertItem是必须借助消息循环来完成任务的。如果我们在主线程中WaitForSingleObject了,必然导致主线程阻塞,也就导致了消息循环的阻塞,最终导致工作线程Crash掉了*_*
总结:
如果在工作线程中有可能涉及到了消息驱动的API,那么不能在主线程中使用WaitForSingleObject一类函数,而必须使用下述的方案:
while(TRUE)
{
DWORD result ;
MSG msg ;
result = MsgWaitForMultipleObjects(1, &readThreadHandle,
FALSE, INFINITE, QS_ALLINPUT);
if (result == (WAIT_OBJECT_0))
{
break;
}
else
{
PeekMessage(&msg, NULL, 0, 0, PM_REMOVE);
DispatchMessage(&msg);
}
}
或者14楼方案。