7

What happens if we forcefully kill a running thread

I have a thread namely RecordThread() which calls some complex and time consuming functions. In these functions I am using try-catch blocks, allocating and deallocation memory and using critical section variables etc.

like

  void RecordThread()
  {
    AddRecord();
    FindRecord();
    DeleteRecord();
    // ...
    ExitThread(0);
   } 

After creating this thread, I am immediately killing it before the thread completes its execution. In this case what happens if the thread is forcefully killed? Do the internal functions (AddRecord, DeleteRecord) complete their execution after we killed the thread?

Wolf
  • 8,482
  • 7
  • 48
  • 92
Aneesh Narayanan
  • 2,776
  • 11
  • 28
  • 44

4 Answers4

15

After creating this thread, I am immediately killing it before the thread completes its execution.

I assume you mean you are using TerminateThread() in the following fashion:

HANDLE thread = CreateThread(...);

// ...
// short pause or other action?
// ...

TerminateThread(thread, 0); // Dangerous source of errors!
CloseHandle(thread);

If that is the case, then no, the thread executing RecordThread() will be stopped exactly where it is at the time that the other thread calls TerminateThread(). As per the notes in the TerminateThread() documentation, this exact point is somewhat random and depends on complex timing issues which are out of your control. This implies that you can't handle proper cleanup inside a thread and thus, you should rarely, if ever, kill a thread.

The proper way to request the thread to finish is by using WaitForSingleObject() like so:

HANDLE thread = CreateThread(...);

// ...
// some other action?
// ...

// you can pass a short timeout instead and kill the thread if it hasn't
// completed when the timeout expires.
WaitForSingleObject(thread, INFINITE);
CloseHandle(thread);
Community
  • 1
  • 1
André Caron
  • 41,491
  • 10
  • 58
  • 117
  • 2
    To make it more explicit: `TerminateThread` can kill your thread in the middle of an `i++` statement. It doesn't try to look for "nice" points such as function calls. – MSalters May 24 '12 at 12:50
  • 1
    Note that POSIX is much different from Win32 API in this respect (by default, unless the thread modified its cancellation settings), it will indeed only kill your thread at a cancellation point. So apart from being dangerous, it's not even equally dangerous everywhere, and thus not "portable" :-) – Damon Jul 18 '12 at 09:19
  • 1
    If it's not obvious from the other comments, some more reasons why you should never use TerminateThread: [Windows started picking up the really big pieces of TerminateThread garbage on the sidewalk, but it's still garbage on the sidewalk](http://blogs.msdn.com/b/oldnewthing/archive/2015/08/14/10635157.aspx) – Robert P Aug 17 '15 at 17:17
3

http://msdn.microsoft.com/en-us/library/windows/desktop/ms682659%28v=vs.85%29.aspx

ExitThread is the preferred method of exiting a thread in C code. However, in C++ code, the thread is exited before any destructors can be called or any other automatic cleanup can be performed. Therefore, in C++ code, you should return from your thread function.

However the function calls will of course be completed because they're called before the ExitThread().

Vladimir Sinenko
  • 4,303
  • 1
  • 24
  • 39
3

killing thread is the last resort - as Andre stated it leaves data in unknown state, you should never do that if thread works on shared object. Better choices are to notify thread to finish work by:

-using global volatile (important) variable which is changed only by main thread and tested by workers
-using signal type synchronization objects (mainly Events) also set by main thread and tested by workers

1

example of Thread that works well:

definition in *.h ------------------------------------

DWORD WINAPI Th_EspectroIF(LPVOID lpData);

CThread th_espectro(Th_EspectroIF);

use in *.cc -----------------------------------

DWORD WINAPI Th_EspectroIF(LPVOID lpData)
{

//Your code...

th_espectro.Stop(true);//stop this Thread 

}

call the Thread with: th_espectro.Start();

RalfFriedl
  • 1,046
  • 3
  • 8
  • 12
  • Welcome to Stack Overflow. Code-only answers are discouraged. How is this answer different from or better than previous answers? – CGritton Nov 12 '18 at 17:53