Shared_ptr 在创建增强线程时从未解除分配
Shared_ptr never deallocated when boost threads created
所以我这里有一个奇怪的情况。我有以下代码:
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 的析构函数中放置了一个打印输出,并验证如果创建该线程它不会被调用。
有人知道这里发生了什么吗?
由于您将指向 class B 的共享指针传递给您的线程,您的线程现在共享该实例。在此线程自然退出之前,不会释放此资源。
根据文档 boost::thread_group
析构函数销毁所有 onwed 线程。 boost::thread
析构函数顺序:
- if defined BOOST_THREAD_DONT_PROVIDE_THREAD_DESTRUCTOR_CALLS_TERMINATE_IF_JOINABLE: If *this has an associated thread of execution, calls detach(), DEPRECATED
- BOOST_THREAD_PROVIDES_THREAD_DESTRUCTOR_CALLS_TERMINATE_IF_JOINABLE: If the thread is joinable calls to std::terminate. Destroys *this.
因此您需要显式加入线程。您可以通过在程序结束时调用 boost::thread_group::join_all()
来做到这一点。
// 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
的行为依赖于实现,但通常它意味着 "stop right now"。不调用析构函数,不调用退出处理程序。
您需要加入或分离该线程。
所以我这里有一个奇怪的情况。我有以下代码:
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 的析构函数中放置了一个打印输出,并验证如果创建该线程它不会被调用。
有人知道这里发生了什么吗?
由于您将指向 class B 的共享指针传递给您的线程,您的线程现在共享该实例。在此线程自然退出之前,不会释放此资源。
根据文档 boost::thread_group
析构函数销毁所有 onwed 线程。 boost::thread
析构函数顺序:
- if defined BOOST_THREAD_DONT_PROVIDE_THREAD_DESTRUCTOR_CALLS_TERMINATE_IF_JOINABLE: If *this has an associated thread of execution, calls detach(), DEPRECATED
- BOOST_THREAD_PROVIDES_THREAD_DESTRUCTOR_CALLS_TERMINATE_IF_JOINABLE: If the thread is joinable calls to std::terminate. Destroys *this.
因此您需要显式加入线程。您可以通过在程序结束时调用 boost::thread_group::join_all()
来做到这一点。
// 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
的行为依赖于实现,但通常它意味着 "stop right now"。不调用析构函数,不调用退出处理程序。
您需要加入或分离该线程。