Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

I am creating a thread using _beginthreadex function. The function address I am passing in it has an infinite while loop (while(1)) . I have the threadid and threadhandle.

I can use 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.

So please suggest if there is a safe way to close,end or kill the thread safely from outside using threadid or threadhandle.

like image 386
lsrawat Avatar asked Mar 25 '15 09:03

lsrawat


People also ask

How do you stop an infinite loop in a thread?

The only way to stop a thread asynchronously is the stop() method.

How do you end an endless loop?

You can press Ctrl + C .

Does an infinite loop ever stop?

Details. An infinite loop is a sequence of instructions in a computer program which loops endlessly, either due to the loop having no terminating condition, having one that can never be met, or one that causes the loop to start over.

How do I stop a while loop in a thread?

Create a Queue from Queue import Queue and pass it to the thread func. Inside the while loop read from the queue (using get ). The main body of the code should put something in the queue that will flag the thread to stop.


3 Answers

You should - literally - never use 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. If your thread has a message loop you can even do it by sending a message to ask it to stop.

like image 65
mg30rg Avatar answered Oct 03 '22 22:10

mg30rg


The proper way is to create an event "kill me", by using CreateEvent, then flag this event when you wish to kill the thread. Instead of having your thread wait while(1), have it wait while(WaitForSingleObject(hevent_killme, 0)). And then you can simply let the thread callback finish and return, no need to call _endthreadex or such.

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.

like image 41
Lundin Avatar answered Oct 03 '22 20:10

Lundin


Instead of while(1), you can use while(continue_running), where continue_running is True when the thread loop should run. When you want to stop the thread, make the controlling thread set continue_running to False. 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.

like image 23
simurg Avatar answered Oct 03 '22 20:10

simurg