简体   繁体   English

如何安全地关闭包含无限循环的线程

[英]How to safely close a THREAD which has a infinite loop in it

I am creating a thread using _beginthreadex function.我正在使用_beginthreadex函数创建一个线程。 The function address I am passing in it has an infinite while loop ( while(1) ) .我传入的函数地址有一个无限的 while 循环( while(1) )。 I have the threadid and threadhandle .我有threadidthreadhandle

I can use TerminateThread(threadhandle,1);我可以使用TerminateThread(threadhandle,1); But it is dangerous.但这是危险的。

The safe way is to kill thread using _endthreadex but it can only be used from inside the thread, and I wanted to kill the thread from outside.安全的方法是使用_endthreadex杀死线程,但它只能从线程内部使用,我想从外部杀死线程。

So please suggest if there is a safe way to close,end or kill the thread safely from outside using threadid or threadhandle .因此,请建议是否有一种安全的方法可以使用threadidthreadhandle从外部安全地关闭、结束或终止线程。

You should - literally - never use TerminateThread() .你应该- 从字面上看 -永远不要使用TerminateThread() And I'm not even joking.我什至不是在开玩笑。 If you are terminating a thread from the outside, all resources reserved in it will be leaked, all state variables accessed inside will have an undetermined state and so on.如果从外部终止一个线程,则其中保留的所有资源都会泄漏,内部访问的所有状态变量都将处于未确定状态等等。


The solution for your problem might be signaling your thread to finish itself.您的问题的解决方案可能是让您的线程自行完成。 It can be done by a volatile variable changed by thread-safe means (see InterlockedIncrement() on that), a Windows event, or something like that.它可以通过线程安全方式更改的 volatile 变量(参见InterlockedIncrement() )、Windows 事件或类似的东西来完成。 If your thread has a message loop you can even do it by sending a message to ask it to stop.如果您的线程有消息循环,您甚至可以通过发送消息要求它停止来实现。

The proper way is to create an event "kill me", by using CreateEvent, then flag this event when you wish to kill the thread.正确的方法是使用 CreateEvent 创建一个事件“杀死我”,然后在您希望杀死线程时标记此事件。 Instead of having your thread wait while(1) , have it wait while(WaitForSingleObject(hevent_killme, 0)) .与其让你的线程等待while(1)while(WaitForSingleObject(hevent_killme, 0))让它等待while(WaitForSingleObject(hevent_killme, 0)) And then you can simply let the thread callback finish and return, no need to call _endthreadex or such.然后你可以简单地让线程回调完成并返回,不需要调用 _endthreadex 之类的。

Example of callback function:回调函数示例:

static DWORD WINAPI thread_callback (LPVOID param)
{
  ...
  while(WaitForSingleObject(hevent_killme, 0) != WAIT_OBJECT_0)
  {
    // do stuff
  }

  return 0;
}

Caller:呼叫者:

HANDLE hevent_killme = CreateEvent(...);
...

void killthread (void)
{
  SetEvent(hevent_killme);
  WaitForSingleObject(hthread_the_thread, INFINITE);
  CloseHandle(hevent_killme);
  CloseHandle(hthread_the_thread);
} 

Never use TerminateThread.永远不要使用 TerminateThread。

Instead of while(1) , you can use while(continue_running) , where continue_running is True when the thread loop should run.您可以使用while(continue_running)代替while(1) ,当线程循环应该运行时, continue_runningTrue When you want to stop the thread, make the controlling thread set continue_running to False .当您想停止线程时,将控制线程设置为continue_runningFalse Of course make sure that you properly guard continue_running with mutexes as it is a variable whose value can be modified from two threads.当然,请确保使用互斥锁正确保护continue_running ,因为它是一个可以从两个线程修改其值的变量。

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

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