在VC2010下!
在对话框类中有个按钮响应的函数void CmyDialog::OnBnClickedbtn1()
{
// TODO: 在此添加控件通知处理程序代码
  m_pThread = AfxBeginThread(ComThread, this));
  if (m_hKillThreadEvent != NULL)
    ResetEvent(m_hKillThreadEvent);
  else
    m_hKillThreadEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
}m_pThread是一个CWinThread的指针
在线程中如果等到线程结束的事件if( WAIT_OBJECT_0 == WaitForSingleObject(pTmyDlg->m_hKillThreadEvent, 0))
{
  pmyDlg->m_bThreadAlive = FALSE;
  AfxEndThread(0);
 }m_bThreadAlive是对话框类的BOOL型的成员函数,代表现在线程是否运行的标志。
因担心在线程成未关闭的情况下,点击对话框的关闭按钮(右上角的红叉),所以在OnClose()处理中关闭线程void CTestDialog::OnClose()
{
  // TODO: 在此添加消息处理程序代码和/
  do
  {
     SetEvent(m_hKillThreadEvent);
     Sleep(50);
  }while(m_bThreadAlive);
  m_pThread = NULL;  if(NULL != m_hKillThreadEvent)
  {
     CloseHandle(m_hKillThreadEvent);
     m_hKillThreadEvent = NULL;
   }
  CDialogEx::OnClose();}发现在点击关闭后,程序死在即,此事件发生没能执行杀死线程的代码do
  {
     SetEvent(m_hKillThreadEvent);
     Sleep(50);
  }while(m_bThreadAlive);
但是不再OnClose中处理,则正常执行,线程能够退出,我是在搞不懂了,这个到底是怎么回事??和对话框的退出有关系吗?

解决方案 »

  1.   


    暂停程序,看看线程中处于什么执行状态, 可能线程中在等待其它事件, 而程序中等待标志, 导致程序死锁,可能在线程中 WaitForMultipleObjects, m_hKillThreadEvent 作为其中一个事件
      

  2.   

    死锁1. OnClose()和WaitForSingleObject(pTmyDlg->m_hKillThreadEvent, 0)不能在一个线程。
    比如都在GUI主线程2. 退出的时候为什么要用while循环?激活一下事件就可以了啊3. m_hKillThreadEvent的值必须相同,m_hKillThreadEvent必须在创建线程前初始化。
      

  3.   

    没有的,我线程中就只有这么一个事件!而且WaitForSingleObject(pTmyDlg->m_hKillThreadEvent, 0),还是立即返回的!应该不会这样啊!
      

  4.   

    首先多谢指教
    1)WaitForSingleObject()是在线程中等待的,不再同一个线程。
    2)我要判断线程是否真的退出了!
    3)m_hKillThreadEvent的值必须相同?什么意思懂!m_hKillThreadEvent创建线程前初始化,我已经这样修改了,但是和我说的一样的情况关闭不了线程!void CmyDialog::OnBnClickedbtn1()
    {
    // TODO: 在此添加控件通知处理程序代码
      if (m_hKillThreadEvent != NULL)
        ResetEvent(m_hKillThreadEvent);
      else
        m_hKillThreadEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
      m_pThread = AfxBeginThread(ComThread, this));
    }
      

  5.   

    判断线程是否退出不一定要阻塞在Onclose里面啊
    线程退出的时候,向对话框Post一条消息。在消息里处理真正退出后的清理
      

  6.   

    UINT CTestDialog::ComThread( LPVOID lparam )
    {
    CTestDialog * pTestDlg = static_cast<CTestDialog * >(lparam);
    pTestDlg->m_bThreadAlive = TRUE;// HANDLE  pEvent = pTestDlg->m_hKillThreadEvent;
      for (;;)
      {
    if( WAIT_OBJECT_0 == WaitForSingleObject(pTestDlg->m_hKillThreadEvent, 5))
    {
    pTestDlg->m_bThreadAlive = FALSE;
      AfxEndThread(0);
    return 0;
      }
            .............................. }//end for(;;) return 0;