Crash in boost::function destructor in my thread pool implementation
Hi
I am trying to implement thread pool in C++ using pthread and boost::function as a wrapper for any function that client would like to call in the worker thread. I want to encapsulate logic related to threads management in one object which is taking ownership of these threads. That means whenever this object is destroyed, threads must be stopped and cleaned up.
I've been testing my code and it turns out that I get segmentation fault when I destroy WorkerThreadManager object while there is boost::function processed in worker thread. See the code in attachment and backtrace from GDB below.
I don't really understand why it happens, as far as I know boost::function is copyable, so once I get a copy of it from the queue, I can pop() it and even destroy whole queue (I prooved that in some small test) and then call the function's copy. So why is destruction of std::queue< boost::function
AMDG On 09/17/2012 01:01 PM, Marcin Adamski wrote:
Hi
I am trying to implement thread pool in C++ using pthread and boost::function as a wrapper for any function that client would like to call in the worker thread. I want to encapsulate logic related to threads management in one object which is taking ownership of these threads. That means whenever this object is destroyed, threads must be stopped and cleaned up.
I've been testing my code and it turns out that I get segmentation fault when I destroy WorkerThreadManager object while there is boost::function processed in worker thread. See the code in attachment and backtrace from GDB below.
I don't really understand why it happens, as far as I know boost::function is copyable, so once I get a copy of it from the queue, I can pop() it and even destroy whole queue (I prooved that in some small test) and then call the function's copy. So why is destruction of std::queue< boost::function
causing problems? Or maybe it is something else.
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. In Christ, Steven Watanabe
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
participants (2)
-
Marcin Adamski
-
Steven Watanabe