【发布时间】:2012-05-15 12:02:19
【问题描述】:
我从 main() 创建了 100 多个线程,所以我只想知道在退出 main() 之前是否需要调用 pthread_join()。
另外,我不需要这些线程生成的数据,基本上所有线程都在做一些独立于 main() 和其他线程的工作。
【问题讨论】:
标签: c multithreading pthreads
我从 main() 创建了 100 多个线程,所以我只想知道在退出 main() 之前是否需要调用 pthread_join()。
另外,我不需要这些线程生成的数据,基本上所有线程都在做一些独立于 main() 和其他线程的工作。
【问题讨论】:
标签: c multithreading pthreads
pthread_join 做了两件事:
如果您在没有加入的情况下退出进程,那么 (2) 将由操作系统为您完成(虽然它不会执行线程取消清理,只是从轨道中删除线程),并且 (1) 不会。所以你是否需要调用pthread_join取决于你是否需要(1)发生。
如果您不需要线程运行,那么正如其他人所说,您也可以将其分离。无法加入分离的线程(因此您不能等待其完成),但如果它完成,它的资源会自动释放。
【讨论】:
是的,如果线程是可附加的,那么 pthread_join 是必须的,否则它会创建一个僵尸线程。
同意上面的答案,只是分享 pthread_join 手册页中的一个注释。
注意事项
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).
【讨论】:
退出时不需要加入,因为所有其他线程和资源都会被自动清理。这假设您实际上希望在main 退出时杀死所有线程。
如果您不需要加入线程,您可以在创建线程之前通过在属性上使用pthread_attr_setdetachstate 将其创建为“分离”线程。分离的线程无法加入,但它们也需要加入。
所以,
如果您希望所有线程在程序完成之前完成,从主线程加入即可完成。
作为替代方案,您可以将线程创建为分离的,并在所有线程退出后从main 返回,使用信号量或互斥+条件变量进行协调。
如果您不需要完成所有线程,只需从 main 返回。所有其他线程将被销毁。您也可以将线程创建为分离线程,这样可以减少资源消耗。
【讨论】:
默认情况下,pthreads 库中的线程被创建为可连接的。
但是,线程可能会分离,从而使它们不再可连接。因为线程在加入之前消耗系统资源,就像进程在其父调用 wait() 之前消耗资源一样,您不打算加入的线程必须分离,这是一种很好的编程习惯。
当然,一旦主例程退出,所有线程资源都会被释放。
如果我们没有这样做(分离),那么当线程终止时,它会产生相当于僵尸进程的线程。除了浪费系统资源外,如果积累了足够多的线程僵尸,我们将无法创建额外的线程。
【讨论】:
默认情况下,线程运行附加,这意味着它需要的资源一直使用,直到线程加入。
根据您的描述,没有人,但线程本身需要线程的资源,因此您可以创建分离的线程或在启动线程之前分离线程。
在创建线程后分离线程调用pthread_detach()。
无论如何,如果您想确保在程序结束之前所有线程都消失了,您应该在离开主线程(程序)之前运行附加的线程并加入它们。
【讨论】:
如果你想确定你的线程已经真正完成,你想调用pthread_join。
如果你不这样做,那么终止你的程序将突然终止所有未完成的线程。
也就是说,您的main 可以等待足够长的时间才能退出。但是,你怎么能确定它是足够的呢?
【讨论】:
如果您的主程序结束,您的应用程序结束并且您的线程死亡......所以您确实需要使用线程连接(或改用 fork)。
【讨论】: