在工作完成后立即删除 boost::thread 对象的最佳方法是啥?

Posted

技术标签:

【中文标题】在工作完成后立即删除 boost::thread 对象的最佳方法是啥?【英文标题】:What’s the best way to delete boost::thread object right after its work is complete?在工作完成后立即删除 boost::thread 对象的最佳方法是什么? 【发布时间】:2011-04-27 14:46:20 【问题描述】:

我使用new 运算符创建boost::thread 对象并继续而不等待该线程完成其工作:

void do_work()

    // perform some i/o work


boost::thread *thread = new boost::thread(&do_work);

我想,工作完成后有必要删除thread。在不显式等待线程终止的情况下,最好的方法是什么?

【问题讨论】:

为什么要动态创建线程? @Martin York:因为我不希望线程对象在离开变量作用域后被销毁。 但是,如果您只是让它超出范围,那么您将无法访问它(因此您会泄漏)。没有访问权限意味着你不能对它做任何事情,并且实际的执行线程仍然存在,所以它看起来毫无意义。注意:您实际上应该从不拥有这样的 RAW 指针。 @Martin York:我知道这一点。也许这是糟糕的代码示例。实际上,我想将指向线程对象的指针存储在某处,以便稍后将其删除。我的问题是如何在线程终止后立即删除它,但事实证明可以在线程终止之前安全地删除线程对象。 【参考方案1】:

boost::thread 对象的生命周期与本机线程的生命周期无关。 boost::thread 对象随时可能超出范围。

来自boost::thread 类documentation

正如文件的生命周期可能与代表文件的 iostream 对象的生命周期不同一样,执行线程的生命周期也可能与代表执行线程的线程对象不同。特别是,在调用 join() 之后,执行线程将不再存在,即使线程对象继续存在直到其正常生命周期结束。反过来也是可能的;如果在没有先调用 join() 的情况下销毁线程对象,则执行线程将继续执行,直到其初始函数完成。

编辑:如果你只需要启动一个线程并且从不调用join,你可以使用线程的构造函数作为一个函数:

    // Launch thread.
boost::thread(&do_work); 

但是,我不建议你这样做,即使你认为你确定线程会在 main() 之前完成。

【讨论】:

谢谢。我是 Boost Threads 的新手,所以问题在于我对它的工作原理有误解。 据我所知,这就是本机线程在大多数平台上的工作方式。因此,除非线程析构函数调用了 join(),否则在出现异常时会一团糟,这只是正常的结果。【参考方案2】:

你可以使用

boost::thread t(&do_work);
t.detach();

一旦线程被分离,它就不再属于boost::thread对象;对象可以被销毁,线程将继续运行。如果对象拥有一个正在运行的线程,boost::thread 析构函数也会调用detach(),因此让t 被销毁将产生相同的结果。

【讨论】:

【参考方案3】:

我建议你使用 boost::shared_ptr,这样你就不用管何时删除线程对象了。

boost::shared_ptr<boost::thread> thread(new boost::thread(&do_work));

【讨论】:

do_work 完成后如何删除这个线程对象?【参考方案4】:

你应该看看thread interruption。

This article也不错。

http://www.boost.org/doc/libs/1_38_0/doc/html/thread/thread_management.html

【讨论】:

以上是关于在工作完成后立即删除 boost::thread 对象的最佳方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章

boost thread:对象被释放后修改

在没有 boost::thread 的情况下 thread_specific_pointer 可以在哪些平台上工作?

C++ 从类的构造函数运行 boost 线程

boost::thread 的线程管理和并行性

boost - thread.join() 停止用户界面

C++ ReadConsoleInput 不适用于 boost::thread