The first thing I would try would be to kick the condition variable in between the cancel and the join, and have your target thread check for cancellation explicitly after it returns from the condition wait.
That's because it may be that the thread is not responding to cancellation while it's in the condition wait (or at all).
POSIX.1c-2004 (v6) states:
The cancelability state and type of any newly created threads, including the thread in which main() was first invoked, shall be PTHREAD_CANCEL_ENABLE
and PTHREAD_CANCEL_DEFERRED
respectively.
That means you have to explicitly check for cancellation with pthread_testcancel()
.
The other option is to actually set the threads cancel type to PTHREAD_CANCEL_ASYNCHRONOUS
when it first starts to run, something like:
int junk;
pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, &junk);
std::cout
<< ((junk==PTHREAD_CANCEL_DEFERRED) ? "Was deferred" : "Wasn't")
<< std::endl;
That is, of course, assuming that's what the problem is. You should be able to test if it is by examining the output of that third line above.
Cancellation is a request to the target thread which it is free to ignore if it wishes, as opposed to the far more evil pthread_kill()
. I'm a great believer in letting threads control their own lifetimes since I've found it invariably leads to fewer concurrency problems.
Aside: In fact, having been bought up in very early editions of pthreads, even before integration into DCE, I still find myself just using a global variable for each thread indicating when it should exit, along with manually kicking mutexes or condition variables to wake the threads up. I guess I should update my methods (or I would if I could see a clear advantage). :-)