是否必须加入非分离线程?

Posted

技术标签:

【中文标题】是否必须加入非分离线程?【英文标题】:Is it mandatory to join a non-detached thread? 【发布时间】:2016-10-17 07:36:53 【问题描述】:

我创建了一个可以通过 2 种不同方法停止的非分离线程。其中一个 (stop()) 通过加入生成的线程来提供同步接口,而另一个 (stopAsync()) 只是将控制变量 m_continue 设置为 false 并且不等待提到的线程完成。

void run()

    while(m_continue)
    
        // Do something
    


void start()

    m_continue = true;
    // Spawn a new thread for run()


void stop()

    m_continue = false;
    // Join to the spawned thread


void stopAsync()

    m_continue = false;

在调用stopAsync() 的情况下,run() 方法中的 while 循环结束,但没有人加入该线程。这种情况下是否有任何资源泄漏?

我无法从文档中弄清楚。 “注释”部分讲述了一些我无法理解的内容。

线程可以是可连接的,也可以是可分离的。如果一个线程是可连接的,那么另一个线程可以调用 pthread_join(3) 来等待线程终止并获取其退出状态。 只有在已终止的可加入线程加入时,其最后的资源才会释放回系统。 当分离的线程终止时,其资源会自动释放回系统:无法加入与线程以获取其退出状态。使线程分离对于应用程序不需要关心其退出状态的某些类型的守护线程很有用。默认情况下,会在可连接状态下创建新线程,除非将 attr 设置为在分离状态下创建线程(使用 pthread_attr_setdetachstate(3))。

https://linux.die.net/man/3/pthread_create

【问题讨论】:

【参考方案1】:

只有当一个终止的可加入线程被加入时,它的最后一个资源才会释放回系统。

这部分文档的含义是,如果您不加入线程,线程退出后将保持分配的一​​些资源。所以这样做类似于在没有free() 的情况下调用malloc() - 它不是“强制性的”,因为如果你不这样做,它不会对你的程序造成直接的问题,但它确实 表示资源泄漏,因此如果您在长时间运行的程序中重复执行此操作,可能会耗尽相关资源。

代替加入线程,您的stopAsync() 可以在设置标志变量之前在另一个线程上调用pthread_detach()

请注意,您的 m_continue 变量应受诸如互斥锁或读写器锁之类的同步原语的保护。

【讨论】:

感谢提醒,m_continue 是一个原子布尔值。

以上是关于是否必须加入非分离线程?的主要内容,如果未能解决你的问题,请参考以下文章

我怎么知道线程是不是是可连接线程?

C++11多线程,线程对象(thread对象)joinable()join()detach()左值智能指针

C++11多线程,线程对象(thread对象)joinable()join()detach()左值智能指针

从分离线程停止主游戏循环的最佳方法

多线程应用程序中的非解剖分配

线程分离