创建boost线程时,shared_ptr永远不会释放

时间:2015-10-02 17:18:15

标签: c++ multithreading boost smart-pointers

所以我这里有一个奇怪的情况。我有以下代码:

int main()
{
    std::shared_ptr<MyClassA> classA = std::shared_ptr<MyClassA>(new MyClassA);
    std::shared_ptr<MyClassB> classB = std::shared_ptr<MyClassB>(new MyClassB(classA));

    boost::thread_group threadGroup;

    // This thread is essentially an infinite loop waiting for data on a socket
    threadGroup.create_thread( boost::bind(&MyClassB::method1, classB) );

    ...do stuff

    return 0;
}

MyClassB会打开几个资源,这些资源在程序退出时不会被释放。但是,如果我删除对create_thread的调用,则会释放资源。我在MyClassB的析构函数中放置了一个打印输出,并验证在创建该线程时它没有被调用。

有人对这里发生的事情有任何见解吗?

3 个答案:

答案 0 :(得分:4)

根据文档boost::thread_group析构函数破坏所有onwed线程。 boost::thread析构函数按顺序:

  
      
  • 如果已定义BOOST_THREAD_DONT_PROVIDE_THREAD_DESTRUCTOR_CALLS_TERMINATE_IF_JOINABLE:如果*这有一个关联的执行线程,则调用detach(),DEPRECATED
  •   
  • BOOST_THREAD_PROVIDES_THREAD_DESTRUCTOR_CALLS_TERMINATE_IF_JOINABLE:如果线程是可连接的,则调用std :: terminate。摧毁*这个。
  •   

所以你需要明确地加入线程。您可以通过在程序结束时调用boost::thread_group::join_all()来完成此操作。

答案 1 :(得分:2)

由于您将共享指针B类传递给您的线程,因此您的线程现在共享该实例。在此线程自然退出之前,不会释放此资源。

答案 2 :(得分:1)

  

// This thread is essentially an infinite loop waiting for data on a socket

这个评论很有说服力。你的线程可能永远运行,远远超过程序的结束。如果是这种情况,则需要在退出main之前分离线程,并且您应该不会看到被调用的析构函数。线程仍处于活动状态并共享该对象的所有权。

  

...do stuff

如果...do stuff不涉及分离或加入该线程,则在Boost中调用未定义的行为。如果您从使用boost::thread切换到使用std::thread,那么未定义的行为会得到很好的定义。

这个明确定义的行为是没有理智的程序员想要调用的东西:破坏可连接的线程会导致调用std::terminate()std::terminate的行为取决于实现,但通常意味着“立即停止”。不调用析构函数,不调用退出处理程序。

您需要加入或分离该线程。