C++ 如何杀死 MFC 线程?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/590792/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 16:08:02  来源:igfitidea点击:

How to kill a MFC Thread?

c++multithreadingmfc

提问by Nick

I spawn a thread using AfxBeginThreadwhich 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_bKillThreadto FALSEin the destructor. But I still need to wait in the destructor until the thread is dead.

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

回答by Brian R. Bondy

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. This is not a safe way to terminate threads though, so please read on.

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

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);If this function returns WAIT_OBJECT_0, then the thread is finished. Instead of INFINITEyou could also put the number of milliseconds to wait before a timeout happens. In this case WAIT_TIMEOUTwill be returned.

使用AfxBeginThread( CWinThread*)的返回值得到成员m_hThread,然后使用WaitForSingleObject(p->m_hThread, INFINITE);如果这个函数返回WAIT_OBJECT_0,则线程结束。而不是INFINITE你也可以在超时发生之前等待毫秒数。在这种情况下WAIT_TIMEOUT将被退回。

Signaling to your thread that it should end:

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

Before doing the WaitForSingleObjectjust set some kind of flag that the thread should exit. Then in your main loop of the thread you would check for that bool value and break the infinite loop. In your destructor you would set this flag then do a WaitForSingleObject.

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

Even better ways:

更好的方法:

If you need even more control you can use something like boost conditions.

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

回答by plan9assembler

BTW, About TerminateThread(), use it this way.

顺便说一句,关于 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;
}

回答by zar

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 WaitForSingleObjectto check the status of the signal or another way is to simply send this thread a message to end itself. This is graceful ending rather killing it.

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

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 = FALSEabove made it possible we still have a valid handle when thread finishes so we can wait on it. 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).

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

回答by Evgeny Lazin

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 函数,这是非常危险的。