调用pthread_join()是否必要?

22
我从我的main()函数中创建了100多个线程,我想知道在退出main()之前是否需要调用pthread_join()。 此外,我不需要这些线程生成的数据,基本上所有线程都是独立于main()和其他线程执行一些工作。
7个回答

37

pthread_join有两个作用:

  1. 等待线程完成。
  2. 清理与该线程相关的任何资源。

如果你没有使用pthread_join而退出进程,操作系统将会为你执行(2)中的清理(虽然它不会进行线程取消清理,只是从轨道上摧毁线程),但(1)不会发生。因此,是否需要调用pthread_join取决于是否需要完成(1)中的操作。

如果你不需要运行线程,那么像其他人所说,可以将其分离。分离的线程不能被加入(因此无法等待它完成),但如果它完成了,它的资源会自动释放。


谢谢您的回复。如果我理解正确,如果主线程退出,所有我的线程都将被终止。因此,为了避免这种情况,我必须调用pthread_join()或pthread_detach()。对于我的情况,由于我不需要main()等待所有线程完成,我将简单地调用pthread_detach()并退出我的main(),最后操作系统将安全地释放所有线程使用的资源吗? - nav_jan
1
@user1271244:不行。如果你分离线程,它们将在进程退出时被终止,这就是为什么我说“如果你不需要线程运行,那么你可以将其分离”。如果你需要它运行,你必须加入它。 - Steve Jessop

6

如果线程是可附加的,则必须使用pthread_join,否则会创建僵尸线程。

同意上面的答案,只是分享一下pthread_join的man页面上的注释。

注释

   After a successful call to pthread_join(), the caller is guaranteed that the target thread has terminated.

   Joining with a thread that has previously been joined results in undefined behavior.

   Failure to join with a thread that is joinable (i.e., one that is not detached), produces a "zombie thread".  Avoid doing this, since each zombie thread consumes some  system  resources,  and  when
   enough zombie threads have accumulated, it will no longer be possible to create new threads (or processes).

3
当你退出时,不需要加入其他线程和资源,因为所有其他线程和资源都将被自动清除。这假设您实际上希望在main退出时杀死所有线程。
如果您不需要与线程一起加入,则可以在创建线程之前使用pthread_attr_setdetachstate将其设置为“分离”线程的属性。分离线程不能被加入,但它们也不需要被加入。
因此,
  1. 如果您希望在程序完成之前所有线程都完成,请从主线程中加入线程。
  2. 作为替代方案,您可以将线程创建为分离的,并在所有线程退出后从main返回,使用信号量或mutex+条件变量协调。
  3. 如果您不需要所有线程全部完成,请直接从main函数中返回。所有其他线程将被销毁。您也可以创建线程作为分离线程,这可能会减少资源消耗。

请注意,在情况(2)下,您的协调可以确保在线程发布信号量或条件变量之前不会退出。这对于所有实际目的来说应该足够好了,但它并不能确保您在线程退出之前不会退出,因为它们在执行通知主线程发生有趣事件的代码后的某个未指定时间退出。 - Steve Jessop

2

默认情况下,pthreads库中的线程是可连接的。

然而,线程可以分离,使它们不再可连接。因为线程消耗系统资源直到被连接,就像进程消耗资源直到其父进程调用wait()一样,您不打算连接的线程必须被分离,这是一种良好的编程实践。

当然,一旦主程序退出,所有线程资源都将被释放。

如果我们未能做到这一点(分离),那么当线程终止时,它会产生线程等效的僵尸进程。除了浪费系统资源外,如果足够多的线程僵尸积累,我们将无法创建其他线程。


1

默认情况下,线程是附加运行的,这意味着它需要的资源会一直被占用,直到该线程被加入。

根据您的描述,除了线程本身,没有其他人需要该线程的资源,因此您可以创建分离的线程或在启动线程之前将其分离。

要在创建线程后分离线程,请调用pthread_detach()

无论如何,如果您想确保程序结束前所有线程都已关闭,您应该将线程附加并在离开主线程(程序)之前加入它们。


0

如果您想确保您的线程已经完成,您需要调用pthread_join

如果您不这样做,那么终止程序将会突然终止所有未完成的线程。

话虽如此,您的main可以等待足够长的时间直到退出。但是,那么您怎么能确定它是足够的呢?


-1
如果您的主线程结束,应用程序也会结束,您的线程也会死亡... 因此,您需要使用线程加入(或者改用 fork)。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接