简体   繁体   中英

(simple) boost thread_group question

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, ie 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.

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);
...

If you don't need a handle to your threads, try using thread_group::create_thread() which alleviates the need to manage the thread at all:

// Snip: Same as previous examples

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

    // launch three threads
    for ( int i = 0; i < 3; ++i )
        g.create_thread( boost::bind( threaded_function, 10 ) );

    // wait for them
    g.join_all();

    cout << result << endl;

    return 0;
}

add_thread() takes ownership of thread you pass in. Thread group deletes the thread. In this example you are deleting memory allocated on stack, pretty much a capital offence.

Member function add_thread()

void add_thread(thread* thrd);

Precondition :

The expression delete thrd is well-formed and will not result in undefined behaviour.

Effects:

Take ownership of the boost::thread object pointed to by thrd and add it to the group.

Postcondition :

this->size() is increased by one.

Not sure if that's what's wrong in your code, or if this is just example bug. Otherwise code looks fine.

It looks none of above actually answered the question.

I met the similar issue. The consequence of this warning (pthread_mutex_lock.c:87: __pthread_mutex_lock: Assertion `mutex->_ data. _owner == 0' failed. Aborted) is that sometimes the program will leak threads and cause a boost_resource_error exception.

The reason looks like the program continues to execute after join_all() although most of threads are still running ( not terminated ).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM