CreateThread, C++

joe_pool_is

Contributor
Joined
Jan 18, 2004
Messages
507
Location
Longview, TX [USA]
I don't use threads very often, and probably because they can be such a pain.

In tutorials, I see this type of syntax for CreateThread:
Code:
HANDLE hThread;
hThread = CreateThread(NULL, 0, ThreadFn, (LPVOID)param, 0, &dwThreadID);
if (hThread)
{
  CloseHandle(hThread);
}
1. Why was the handle closed as soon as the thread was started?

2. How do I tell when the thread is finished? My current understanding is that I have to poll GetExitCodeThread to determine if my thread is STILL_ACTIVE or if it has ended and returned its exit code. There should be a better way!
Code:
if (hThread != NULL)
{
  DWORD dwExit;
  if (GetExitCodeThread(hThread, &dwExit))
  {
    if (dwExit == STILL_ACTIVE)
      TerminateThread(hThread, dwExit);
  }
  else if (dwExit != 0) // where 0 = ThreadFn's return value
    ExitThread(dwExit);
  CloseHandle(hThread);
  // above is where it seems like HANDLEs should be closed
}

3. What if I wanted to kill this thread? Is this the way?
Code:
PostThreadMessage(dwThreadID, WM_CLOSE, 0, 0);

Thanks in advance!
 
Threading questions

  1. Handles which are no longer needed should be closed to free up any resources which may be allocated to them. In the case of a thread, the resources may be automatically freed when the thread terminates, but it's good practice to close all handles as soon as possible. Since CreateThread returns an open handle, it should be closed if no longer needed.

  2. You can poll it in this way, or you can wait on it with WaitForSingleObject and other methods, if you need the current thread to to wait for the other thread to finish. When you think about it, this makes total sense - testing for anything will always involve either polling (eg GetExitCodeThread) or blocking (eg WaitForSingleObject). It is no different for threads.

  3. Strictly speaking, the correct way to terminate a thread is to allow it to terminate itself. If the thread is in a message loop then PostThreadMessage should work as you described (though WM_QUIT might be a more reliable message).

    If it is not in a message loop, you could use a flag variable which the other thread periodically checks and when signalled, returns from each function, unwinding the call stack back to its ThreadProc and then returning from that also.

    If this is not possible, due to an uninterruptable blocking operation for example, then TerminateThread may be your only option, but such cases are rare.

Good luck :cool:
 
Re: Threading questions

Hi Mr. Paul (I feel like I'm "talking to the hand" now),

Please elaborate: After creating a thread, it seems to me like WaitForSingleObject would block the main thread's process until the thread finished. Then why have a thread in the first place? Right now, the only time I use WaitForSingleObject is after I tell the thread to terminate. Is this the only place it should be used?

I have a thread which continually scans a serial port for data. If I were to close the handle immediately after creating it, would the thread's resources be released and the thread terminated?

Also, say CreateThread returns HANDLE h:
Code:
int i;
[FONT=Courier New]HANDLE h = CreateThread(...);[/FONT]
[FONT=Courier New]if (h != NULL)[/FONT]
[FONT=Courier New] DoThis();[/FONT]
[FONT=Courier New]else[/FONT]
[FONT=Courier New] i = GetLastError();[/FONT]
From the example above, it seems like a good way test to check a thread's validity would be to check that the HANDLE is non-NULL; however, whenever the thread terminates (or is terminated), the handle does not get set to NULL.

Before, I was manually setting the handle to NULL after the thread terminated, but a fellow programmer told me this was not considered good programming style since something could still try to send a message to the handle that I erased.

Any thoughts on this?

It still seems like setting the handle to NULL when the thread has terminated is the best thing to do. Maybe I could set the handle to NULL inside the procedure that processes the PostThreadMessage? ...but I do not know where this would be handled by my thread, since (to my knowledge) it is not a window and does not have a WndProc() messaging section.

Thanks for your help, too!
 
Threads, handles, and hands

After creating a thread, it seems to me like WaitForSingleObject would block the main thread's process until the thread finished. Then why have a thread in the first place? Right now, the only time I use WaitForSingleObject is after I tell the thread to terminate. Is this the only place it should be used?

Yes, using WaitForSingleObject will cause the calling thread to block. It depends what you want here - either you just want the status of the other thread, in which case GetExitCodeThread will suffice, or you want to wait for the other thread to finish (called joining), in which case you use WFSO or similar.

I have a thread which continually scans a serial port for data. If I were to close the handle immediately after creating it, would the thread's resources be released and the thread terminated?

No. The kernel maintains its own handle to the thread until it has terminated. Closing your handle will not affect the thread whatsoever.

From the example above, it seems like a good way test to check a thread's validity would be to check that the HANDLE is non-NULL; however, whenever the thread terminates (or is terminated), the handle does not get set to NULL.

The above method is the correct way to test that the thread was created. The handle can then be used to query the status of the created thread (eg whether it has terminated). If you're worried that the thread would have been created and terminated before you had a chance to test it then you could create the thread in the suspended state and resume it when ready.

Before, I was manually setting the handle to NULL after the thread terminated, but a fellow programmer told me this was not considered good programming style since something could still try to send a message to the handle that I erased.

If your code is not properly written then yes, something could still try to manipulate the thread via the closed handle, but as far as I know this would not cause any problems besides an error code being returned. I wonder what your fellow programmer would suggest - never closing handles on the off-chance that the handle might be used elsewhere? - Now that would definitely be bad practice.

It still seems like setting the handle to NULL when the thread has terminated is the best thing to do.

A handle is just another variable. The OS doesn't care two hoots what the value of the variable itself is - what it cares about is that you close handles which are no longer needed, using CloseHandle. Of course, after closing the handle you should set the handle value to NULL to avoid trying to close the same handle twice.

Maybe I could set the handle to NULL inside the procedure that processes the PostThreadMessage? ...but I do not know where this would be handled by my thread, since (to my knowledge) it is not a window and does not have a WndProc() messaging section.

If your thread has a message-processing loop (using GetMessage or PeekMessage) then PostThreadMessage could be used to terminate it. If not (as in your case), you should have a variable which the thread periodically checks and when true, terminates itself. For example:

Code:
BOOL bRunning;

DWORD WINAPI MyThreadProc(LPVOID lpParam)
{
    //Init code

    bRunning = TRUE;
    while (bRunning) {
        //Do some processing
    }

    //Termination code
}


//Elsewhere in code:
VOID StopMyThread()
{
    bRunning = FALSE;
}

Good luck :cool:
 
Back
Top