所以我这里有一个奇怪的情况。我有以下代码:
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的析构函数中放置了一个打印输出,并验证在创建该线程时它没有被调用。
有人对这里发生的事情有任何见解吗?
答案 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
的行为取决于实现,但通常意味着“立即停止”。不调用析构函数,不调用退出处理程序。
您需要加入或分离该线程。