Steven Watanabe <watanabesj@gmail.com> wrote: You have a race condition in your destructor. pthread_cancel, does *not* wait for the thread to terminate. You need to join the threads before the queue is destroyed. It's funny and actualy quite often - while I was writing response to this quotation I found a bug, thank you! So I was about to write: "The race is only between cancellation point after sem_wait() call and manager->m_results.pop() in WorkerThreadManager::WorkerThread(), and my example uses sleep to be "sure" that WorkerThreadManager destruction occurs when A::Fun() is during sleep, so there is no access to queue". And the bug is trivial: I do pop() on an empty queue, I inteded to do it on m_tasks instead of m_results... But why this bug caused crash when queue was being destructed? Before I fixed this bug I also tried joining threads after cancellation, but it caused pthread_join to hang on a thread that was during task execution. Why did it happen? I use deferred cancellation so thread should be gently cancelled on sleep() which is a cancellation point. Regards Marcin Adamski