24

我正在尝试编写一个相当简单的线程应用程序,但对 boost 的线程库还是陌生的。我正在研究的一个简单的测试程序是:

#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;
}

但是,当我编译并运行这个程序时,我得到一个输出

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

显然,结果是正确的,但我担心这个错误消息,特别是因为具有基本相同结构的实际程序卡在 join_all() 点。有人可以向我解释发生了什么吗?有没有更好的方法来做到这一点,即启动多个线程,将它们存储在外部容器中,然后等待它们全部完成后再继续程序?

谢谢你的帮助。

4

4 回答 4

29

我认为您的问题是由程序退出时调用的 thread_group 析构函数引起的。线程组想要负责破坏你的线程对象。另请参阅boost::thread_group文档。

您正在堆栈上创建线程对象作为主函数范围内的局部变量。因此,当程序退出并且 thread_group 试图删除它们时,它们已经被破坏了。

作为一种解决方案,使用new在堆上创建线程对象,并让 thread_group 处理它们的销毁:

boost::thread *t1 = new boost::thread(threaded_function, 10);
...
g.add_thread(t1);
...
于 2009-08-07T22:01:45.547 回答
28

如果您不需要线程句柄,请尝试使用 thread_group::create_thread() 来完全减轻管理线程的需要:

// 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;
}
于 2011-07-19T22:35:40.217 回答
3

add_thread() 获取您传入的线程的所有权。线程组删除线程。在此示例中,您正在删除分配在堆栈上的内存,这几乎是一种死罪。

成员函数add_thread()

void add_thread(thread* thrd);

前提条件

表达式 delete thrd 格式正确,不会导致未定义的行为。

效果:

获取 thrd 指向的 boost::thread 对象的所有权并将其添加到组中。

后置条件

this->size() 加一。

不确定这是否是您的代码有问题,或者这只是示例错误。否则代码看起来很好。

于 2009-08-07T21:06:25.363 回答
1

看起来以上都没有真正回答这个问题。

我遇到了类似的问题。此警告的后果(pthread_mutex_lock.c:87: __pthread_mutex_lock: Assertion `mutex->_ data._owner == 0' failed. Aborted)是有时程序会泄漏线程并导致 boost_resource_error 异常。

原因看起来程序在 join_all() 之后继续执行,尽管大多数线程仍在运行(未终止)。

于 2013-07-12T13:39:51.057 回答