(simple) boost thread_group question

RandomGuy picture RandomGuy · Aug 7, 2009 · Viewed 31.9k times · Source

I'm trying to write a fairly simple threaded application, but am new to boost's thread library. A simple test program I'm working on is:

#include <iostream>
#include <boost/thread.hpp>

int result = 0;
boost::mutex result_mutex;

boost::thread_group g;

void threaded_function(int i)
{
    for(; i < 100000; ++i) {}

    {
        boost::mutex::scoped_lock lock(result_mutex);
        result += i;
    }
}

int main(int argc, char* argv[])
{
    using namespace std;

    // launch three threads
    boost::thread t1(threaded_function, 10);
    boost::thread t2(threaded_function, 10);
    boost::thread t3(threaded_function, 10);

    g.add_thread(&t1);
    g.add_thread(&t2);
    g.add_thread(&t3);

    // wait for them
    g.join_all();

    cout << result << endl;

    return 0;
}

However, when I compile and run this program I get an output of

$ ./test 
300000
test: pthread_mutex_lock.c:87: __pthread_mutex_lock: Assertion `mutex->__data.__owner == 0' failed.
Aborted

Obviously, the result is correct but I'm worried about this error message, especially because the real program, which has essentially the same structure, is getting stuck at the join_all() point. Can someone explain to me what is happening? Is there a better way to do this, i.e. launch a number of threads, store them in a external container, and then wait for them all to complete before continuing the program?

Thanks for your help.

Answer

VoidPointer picture VoidPointer · Aug 8, 2009

I think you problem is caused by the thread_group destructor which is called when your program exits. Thread group wants to take responsibility of destructing your thread objects. See also in the boost::thread_group documentation.

You are creating your thread objects on the stack as local variables in the scope of your main function. Thus, they have already been destructed when the program exits and thread_group tries to delete them.

As a solution, create your thread objects on the heap with new and let the thread_group take care of their destruction:

boost::thread *t1 = new boost::thread(threaded_function, 10);
...
g.add_thread(t1);
...