简体   繁体   English

如何杀死MFC线程?

[英]How to kill a MFC Thread?

I spawn a thread using AfxBeginThread which is just an infinite while loop: 我使用AfxBeginThread生成一个线程,它只是一个无限的while循环:

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

How do I kill off this thread in my class destructor? 如何在类析构函数中删除此线程?

I think something like 我觉得有点像

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

and then set m_bKillThread to FALSE in the destructor. 然后在析构函数中将m_bKillThread设置为FALSE But I still need to wait in the destructor until the thread is dead. 但是我仍然需要在析构函数中等待,直到线程死亡。

Actively killing the thread: 主动杀死线程:

Use the return value of AfxBeginThread ( CWinThread* ) to get the thread handle ( m_hThread ) then pass that handle to the TerminateThread Win32 API. 使用AfxBeginThreadCWinThread* )的返回值来获取线程句柄( m_hThread ),然后将该句柄传递给TerminateThread Win32 API。 This is not a safe way to terminate threads though, so please read on. 这不是一种终止线程的安全方法,所以请继续阅读。

Waiting for the thread to finish: 等待线程完成:

Use the return value of AfxBeginThread ( CWinThread* ) to get the member m_hThread, then use WaitForSingleObject(p->m_hThread, INFINITE); 使用AfxBeginThreadCWinThread* )的返回值来获取成员m_hThread,然后使用WaitForSingleObject(p->m_hThread, INFINITE); If this function returns WAIT_OBJECT_0 , then the thread is finished. 如果此函数返回WAIT_OBJECT_0 ,则线程结束。 Instead of INFINITE you could also put the number of milliseconds to wait before a timeout happens. 您可以在超时发生之前等待毫秒数而不是INFINITE In this case WAIT_TIMEOUT will be returned. 在这种情况下,将返回WAIT_TIMEOUT

Signaling to your thread that it should end: 向您的线程发信号通知它应该结束:

Before doing the WaitForSingleObject just set some kind of flag that the thread should exit. 在执行WaitForSingleObject之前,只需设置线程应退出的某种标志。 Then in your main loop of the thread you would check for that bool value and break the infinite loop. 然后在线程的主循环中,您将检查该bool值并打破无限循环。 In your destructor you would set this flag then do a WaitForSingleObject . 在析构函数中,您将设置此标志,然后执行WaitForSingleObject

Even better ways: 更好的方法:

If you need even more control you can use something like boost conditions . 如果您需要更多控制,您可以使用类似增强条件的东西。

BTW, About TerminateThread(), use it this way. BTW,关于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;
}

First you have to start the thread in a way so MFC doesn't delete the thread object when it's finished , the default setting for MFC thread is to delete itself so you want to turn that off. 首先,你必须启动线程的方式,使MFC不会删除时,它的线程对象完成 ,为MFC线程默认设置是让您随心所欲把它们关掉删除自身。

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

Now in the thread, you want a mechanism that the caller thread can send it a signal to end itself. 现在在线程中,您需要一种机制,调用者线程可以向其发送信号以结束自身。 There are multiple ways, one is the WaitForSingleObject to check the status of the signal or another way is to simply send this thread a message to end itself. 有多种方法,一种是WaitForSingleObject来检查信号的状态,另一种方法是简单地向这个线程发送一条消息来结束自己。 This is graceful ending rather killing it. 这是优雅的结局,而不是杀死它。

While this thread is ending itself (= exiting the thread function, cleaning up), you can have the main thread wait on it to finish before it exits. 当这个线程结束时(=退出线程函数,清理),你可以让主线程在它退出之前等待它完成。

     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;
     }

Note setting m_bAutoDelete = FALSE above made it possible we still have a valid handle when thread finishes so we can wait on it. 注意设置上面的m_bAutoDelete = FALSE使我们在线程完成时仍然有一个有效的句柄,所以我们可以等待它。 The last thing you want to do now is delete the CWinThread object to free its memory (since we took the responsibility to do that). 你现在要做的最后一件事是删除CWinThread对象以释放它的内存(因为我们负责这样做)。

You must wait, until thread do all stuff. 你必须等待,直到线程做所有的事情。

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

beware using TerminateThread function, this is very dangerous. 注意使用TerminateThread函数,这是非常危险的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM