【问题标题】:How to kill a MFC Thread?如何杀死 MFC 线程?
【发布时间】:2010-10-10 02:24:07
【问题描述】:

我使用 AfxBeginThread 生成一个线程,这只是一个无限的 while 循环:

UINT CMyClass::ThreadProc( LPVOID param )
{
  while (TRUE)
  {
      // do stuff
  }
  return 1;
}

如何在我的类析构函数中杀死这个线程?

我觉得有点像

UINT CMyClass::ThreadProc( LPVOID param )
{
  while (m_bKillThread)
  {
      // do stuff
  }
  return 1;
}

然后在析构函数中将m_bKillThread 设置为FALSE。但是我仍然需要在析构函数中等待,直到线程死亡。

【问题讨论】:

    标签: c++ multithreading mfc


    【解决方案1】:

    主动杀死线程:

    使用AfxBeginThread (CWinThread*) 的返回值获取线程句柄 (m_hThread),然后将该句柄传递给 TerminateThread Win32 API。不过,这不是终止线程的安全方法,因此请继续阅读。

    等待线程结束:

    使用AfxBeginThread(CWinThread*)的返回值得到成员m_hThread,然后使用WaitForSingleObject(p->m_hThread, INFINITE);如果这个函数返回WAIT_OBJECT_0,那么线程就结束了。除了INFINITE,您还可以输入超时发生前等待的毫秒数。在这种情况下,WAIT_TIMEOUT 将被返回。

    向您的线程发出信号,表明它应该结束:

    在执行WaitForSingleObject 之前,只需设置线程应该退出的某种标志。然后在线程的主循环中,您将检查该布尔值并打破无限循环。在您的析构函数中,您将设置此标志,然后执行WaitForSingleObject

    更好的方法:

    如果您需要更多控制权,可以使用 boost conditions 之类的东西。

    【讨论】:

      【解决方案2】:

      顺便说一句,关于 TerminateThread(),这样用吧。

      DWORD exit_code= NULL;
      if (thread != NULL)
      {
          GetExitCodeThread(thread->m_hThread, &exit_code);
          if(exit_code == STILL_ACTIVE)
          {
              ::TerminateThread(thread->m_hThread, 0);
              CloseHandle(thread->m_hThread);
          }
          thread->m_hThread = NULL;
          thread = NULL;
      }
      

      【讨论】:

      • 你泄漏,你必须调用:删除线程;在发出之前线程 = NULL;
      【解决方案3】:

      首先,您必须以某种方式启动线程,以便 MFC 在线程对象为 finished 时不会删除它,MFC 线程的默认设置是删除自身,因此您想将其关闭。

         m_thread = AfxBeginThread(ThreadProc, this, THREAD_PRIORITY_NORMAL ,CREATE_SUSPENDED);
         m_thread->m_bAutoDelete = FALSE;
         m_thread->ResumeThread();
      

      现在在线程中,您需要一种机制,调用者线程可以向其发送信号以结束自身。有多种方法,一种是WaitForSingleObject 来检查信号的状态,另一种方法是简单地向该线程发送一条消息以结束自身。这是一个优雅的结局,而不是杀死它。

      当这个线程自己结束时(= 退出线程函数,清理),你可以让主线程在它退出之前等待它完成。

           int wait = 2000 // seconds ( I am waiting for 2 seconds for worker to finish)
           int dwRes = WaitForSingleObject( m_thread->m_hThread, wait);
           switch (dwRes)
           {
           case WAIT_OBJECT_0:
               TRACE( _T("worker thread just finished") ); break;
           case WAIT_TIMEOUT:
               TRACE( _T("timed out, worker thread is still busy") ); break;
           }
      

      注意上面的设置m_bAutoDelete = FALSE 使得当线程完成时我们仍然有一个有效的句柄,所以我们可以等待它。您现在要做的最后一件事是删除 CWinThread 对象以释放其内存(因为我们负责这样做)。

      【讨论】:

        【解决方案4】:

        你必须等待,直到线程完成所有事情。

        if(WaitForSingleObject(thread_handle, INFINITE) == WAIT_OBJECT_0) 
            ;//all right
        else
            ;//report error
        

        小心使用 TerminateThread 函数,这很危险。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2011-06-29
          • 1970-01-01
          • 2011-02-13
          • 2011-04-19
          • 1970-01-01
          • 2011-04-25
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多