【问题标题】:What happens with unjoined and not detached threads when the whole process terminates?当整个进程终止时,未加入和未分离的线程会发生什么?
【发布时间】:2017-10-27 23:59:09
【问题描述】:

预计未调用pthread_detach() 的线程应在主线程从main() 返回或调用exit() 之前进行pthread_join()ed。

但是,如果不满足此要求会怎样?当一个进程终止时它仍然包含未加入和未分离的线程时会发生什么?

得知这些其他线程的资源在系统重新启动之前不会被回收,我会觉得很奇怪。但是,如果这些资源会被回收,那么加入或分离可能就不需要费心了,不是吗?

【问题讨论】:

  • 在 Linux glibc 2.3 及更高版本中,当您从main() 返回时实际上调用exit_group(),或调用exit()_exit()_Exit();这将终止进程中的所有线程,并退出进程,释放所有正常的系统资源。 (只有持久性资源,如文件、fifo、非匿名共享内存等,才能继续存在。)您希望线程以有序方式退出的真正原因是确保它们已完成对持久性数据的处理,而不是例如在写入文件的过程中。
  • '得知这些其他线程的资源在系统重新启动之前不会被回收,我会觉得很奇怪'为什么'奇怪'?如果它们在进程终止时没有被释放,我会觉得很奇怪。
  • @NominalAnimal '以确保他们已经完成了对持久数据的处理,而不是例如在写入文件的过程中,依赖此类活动进行正确操作的应用程序在第一次断电或被“kill -9”或任务管理器关闭时会遇到麻烦。如果需要任何必要的文件清理,应该在进程启动时完成,而不是关闭。
  • @ThingyWotsit:这太疯狂了。我运行并行模拟,通常每个线程一个子系统。当我希望模拟提前停止时,我喜欢使用信号。我没有让进程(和所有线程)立即退出,而是使用信号设置一个标志,告诉每个工作人员保存他们的状态并优雅地退出。我不知道你运行或编写的程序是什么,但我希望我不依赖它们中的任何一个......
  • @NominalAnimal 好吧,我编写的应用程序保证在电源故障和管理员进程外终止后正确重启。我想,鉴于当今许多应用程序的脆弱性,这可能被认为是过度设计的。

标签: c pthreads posix


【解决方案1】:

这取决于操作系统。典型的现代操作系统确实会回收废弃线程使用的内存和描述符(句柄)。这类似于动态分配内存的工作方式:典型的现代系统会在进程退出时回收它,即使该进程从未显式释放内存。对于某些不寻常的程序,这可能是一种有意义的性能优化,因为释放大量小资源需要时间,而操作系统可能能够更快地完成。

【讨论】:

【解决方案2】:

但是,如果不满足此要求会怎样?当一个进程终止时它仍然包含未加入和未分离的线程时会发生什么?

在任何具有非古老 POSIX 线程的系统上,当主线程执行 SYS_exit 系统调用时,未连接的线程会简单地“蒸发”到空间中。

得知这些其他线程的资源在系统重新启动之前不会被回收,我会觉得很奇怪。

他们会的。

但是,如果这些资源会被回收,那么可能就不需要担心加入或分离,不是吗?

这取决于这些线程做什么。危险在于退出数据竞争。

C++中,全局变量被破坏(通常通过atexit或等效的注册机制),FILE句柄被删除等等。

如果未加入的线程尝试访问任何此类资源,它可能会因SIGSEGV 而崩溃,可能会产生core 转储和不干净的进程退出代码,这两者通常都是不可取的。

【讨论】:

  • '当主线程执行 SYS_exit 系统调用时' - 为什么是'主线程'?当然,任何线程都可以吗?
  • 对于一个重要的操作系统来说,在释放这些线程可能访问的任何资源之前停止所有进程线程的执行是正常的(实际上是必要的)。
猜你喜欢
  • 1970-01-01
  • 2017-06-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-01-28
相关资源
最近更新 更多