tags:

views:

45

answers:

1

I'm trying to spawn and then join two threads using MS VS 6.0 (2003), MS .NET Framework 1.1.

The following seems to be a reasonable solution:

CWinThread* thread1 = AfxBeginThread(worker, &parallel_params);
CWinThread* thread2 = AfxBeginThread(worker, &parallel_params);
WaitForSingleObject(thread1->m_hThread, INFINITE);
WaitForSingleObject(thread2->m_hThread, INFINITE);

but my main concern has to do with this statement in the documentation: "If this handle is closed while the wait is still pending, the function's behavior is undefined." When do handles get closed? Does ending the worker proc close the handle? If so, am I in trouble? Is this really a reasonable solution??

A: 

In order to be able to safely wait on the thread's handle, you should:

  1. Start the thread suspended
  2. Set the m_bAutoDelete member to false, so that the returned CWinThread* is not deleted automatically once the thread exits
  3. Resume the thread
  4. And finally wait on the handle the way you do.

Alternatively, you can start the thread suspended, then duplicate the handle, leave m_bAutoDelete as is, and finally wait on the new handle. This way the CWinThread* will indeed be deleted, but you'll still have a handle to wait on. Also, don't forget to close the handle once your done waiting on it.

If you leave your code as is, you might not even get to wait on a closed handle. If the thread exits you get to the wait function, the CWinThread* pointer might point to a deleted object, and you'll get an exception.

eran
Very helpful, thanks! A few followup questions.1. If I follow your approach, do I have to do something to then delete the thread and if so how do I do it? If the thread is deleted (by me or automatically) does the handle still have to be closed, too? And in any case, how is a handle closed?2. If I'm confident the worker threads will not terminate immediately, would it suffice to have a single WaitForMultipleObjects and that way avoid having to deal with handles myself?Thanks again!
1. When the thread is done, you should delete the CWinThread* using regular delete. If you look in CWinThread's destructor code, you'll see it also closes the handle. However, if you duplicate the handle closing the dup is up to you.2. WaitForMul... doesn't change the race condition situation. If you wait on handles, you have to somewhat deal with them (though sometimes indirectly, as described above). Not much gain there, I'm afraid.
eran
That seems to about cover it. Time to hit the docs and give it a try.Thanks again. Great answers!