C++11:如何在 std::thread 的执行函数退出后立即加入它?

Posted

技术标签:

【中文标题】C++11:如何在 std::thread 的执行函数退出后立即加入它?【英文标题】:C++11: How can I join a std::thread as soon as its execution function exits? 【发布时间】:2018-05-25 20:09:25 【问题描述】:

我有以下具有 std::thread 作为其成员字段之一的类:

class MyClass 
private:
    std::thread auxThread;
    void run();
public:
    ~MyClass();
    void start();


MyClass:~MyClass() 
    if (auxThread.joinable())
        auxThread.join();


void MyClass::run() 
    //do stuff


void MyClass::start() 
    auxThread = std::thread (&MyClass::run, this); //Move assignment

我可以按需启动 auxThread,这要归功于使用空构造函数对其进行初始化,然后将其移动分配给与实际执行线程关联的 std::thread 对象(通过 start() 函数),但是最小化系统资源使用我想在 run() 退出后立即将 auxThread 加入主线程,即当 auxThread 的工作完成时,而不是在 MyClass 析构函数中。看起来condition_variable 可以用来唤醒休眠的主线程并完成此操作,但我不想阻塞主线程,除非(希望)短暂地使用 join()。

两个问题:

    如果线程从未与主线程连接,或者线程和所有相关资源在执行函数退出时释放(例如 join() 将大概是不必要的并立即返回)?

    是否可以从主线程调用 auxThread 上的 join() 以响应 run() 退出而不阻塞主线程?

【问题讨论】:

1) 不,这不是资源消耗,2) 不是join(),但如果你真的不关心它,你可以detach() 线程 请不要过早优化。 请注意,您要调用join() 的主要原因不是为了释放资源,而是为了保证线程在在修改进程之前 已经死掉并消失了/environment 的方式可能会导致线程调用未定义的行为。特别是你想在你的程序退出之前join()所有线程,因为在main()返回之后执行的运行时清理代码可能会清理正在运行的线程可能假设仍然存在的数据结构,从而导致偶尔的崩溃如果在main() 返回时任何线程仍在运行,则关闭。 【参考方案1】:

如果线程从未加入主线程,则该线程的执行函数已退出资源消耗

也许吧。这取决于您的实现,但通常不会。

是执行函数退出时释放的线程和所有相关资源

可能,如果不是,那么操作系统会尽快处理。这也是实现定义的。

是否可以从主线程调用 auxThread 上的 join() 以响应 run() 退出而不阻塞主线程?

是的,但这没有任何意义。 join 唯一做的就是阻塞,直到正在执行的函数完成。在run 完成执行后再次调用join 是不必要的,基本上是无操作。

此外,线程中的“资源”很少。我不希望只为像您这样的单个线程分配大量内存。现在 RAM 相当便宜,所以您不必担心,因为您没有并行执行 5M 线程,这在传统计算机上无论如何都没有意义。

【讨论】:

以上是关于C++11:如何在 std::thread 的执行函数退出后立即加入它?的主要内容,如果未能解决你的问题,请参考以下文章

在 C++11 中通过引用 std::thread 传递对象

C++ 11 std::thread 循环

来自 c++11 的 std::thread 问题

c++11 future promise

C++11 多线程std:: async与std::thread的区别

C++ std::thread概念介绍