TerminateThread is a bad idea, especially if your thread uses synchronization objects such as mutexes. It can lead to unreleased memory and handles, and to deadlocks, so you're correct that you need to do something else.
Typically, the way that a thread terminates is to return from the function that defines the thread. The main thread signals the worker thread to exit using an event object or a even a simple boolean if it's checked often enough. If the worker thread waits with WaitForSingleObject
, you may need to change it to a WaitForMultipleObjects
, where one of the objects is an event. The main thread would call SetEvent
and the worker thread would wake up and return.
We really can't provide any useful code unless you show us what you're doing. Depending on what the worker thread is doing and how your main thread is communicating information to it, it could look very different.
Also, under [now very old] MSVC, you need to use _beginthreadex
instead of CreateThread
in order to avoid memory leaks in the CRT. See MSKB #104641.
Update:
One use of worker thread is as a "timer", to do some operation on regular intervals. At the most trivial:
for (;;) {
switch (WaitForSingleObject(kill_event, timeout)) {
case WAIT_TIMEOUT: /*do timer action*/ break;
default: return 0; /* exit the thread */
}
}
Another use is to do something on-demand. Basically the same, but with the timeout set to INFINITE
and doing some action on WAIT_OBJECT_0
instead of WAIT_TIMEOUT
. In this case you would need two events, one to make the thread wake up and do some action, another to make it wake up and quit:
HANDLE handles[2] = { action_handle, quit_handle };
for (;;) {
switch (WaitForMultipleObject(handles, 2, FALSE, INFINITE)) {
case WAIT_OBJECT_0 + 0: /* do action */ break;
default:
case WAIT_OBJECT_0 + 1: /* quit */ break;
}
}
Note that it's important that the loop do something reasonable if WFSO/WFMO return an error instead of one of the expected results. In both examples above, we simply treat an error as if we had been signaled to quit.
You could achieve the same result with the first example by closing the event handle from the main thread, causing the worker thread get an error from WaitForSingleObject
and quit, but I wouldn't recommend that approach.