进程是不是会在退出时自动清理 pthreads 占用的资源
Posted
技术标签:
【中文标题】进程是不是会在退出时自动清理 pthreads 占用的资源【英文标题】:Does the process automatically clean up the resources taken by pthreads upon exit进程是否会在退出时自动清理 pthreads 占用的资源 【发布时间】:2014-07-31 05:29:09 【问题描述】:假设我有这样的代码:
void *my_thread(void *data)
while (1)
void foo_init(struct my_resource *res)
pthread_create(&res->tid, NULL, my_thread, res);
/* Some init code */
void foo_exit(void)
/* Some exit code */
场景是这样的。当进程被初始化时,函数foo_init()
被调用,并带有一个指向我分配的资源的指针(分配是由一些其他函数自动完成的,它不受我的控制)。在函数中,我创建了一个pthread
,它在无限循环中运行。
当进程即将终止时,函数foo_exit()
被调用,但这次没有指向我的资源的指针,因此我无法调用pthread_join()
,因为我的tid
被包含在my_resource
结构中。
现在我的问题是,与pthreads
有关的资源是否在操作系统终止进程时被销毁?如果是,我该如何确定。
在不调用pthread_join()
的情况下终止进程是否安全?
提前致谢。
【问题讨论】:
是什么阻止了您使线程可用于正确加入(除了糟糕的退出策略)? @WhozCraig 代码实现有点基于框架。函数 foo_init() 和 foo_exit() 实际上是回调函数,因此不在我的控制之下。 【参考方案1】:如果您在谈论分配的内存,是的。当一个进程退出时,分配给该进程的所有虚拟内存页面都将返回给系统,系统将清理您进程内分配的所有内存。
通常操作系统应该在退出时清理与进程相关的所有资源。它将处理关闭文件句柄(可以包括套接字和 RPC 机制)、擦除堆栈以及清理任务的内核资源。
简短的回答,如果操作系统在处理后没有清理它是操作系统中的错误。但是我们谁都不会写有缺陷的软件,对吧?
【讨论】:
那么在不调用pthread_join()
的情况下终止进程是否安全?
@raghav3276:终止进程会固有地终止其所有线程并执行许多其他操作。请参阅pubs.opengroup.org/onlinepubs/9699919799/functions/_Exit.html 了解进程终止的后果。
在其中一个注释中提到了Termination of a process does not directly terminate its children
,那么这也会影响pthreads吗?
在任何状态下终止进程本质上都不是不安全的(除非操作系统错误)。要理解的是软件本质上是有缺陷的,所以你应该编写代码以使其正常运行。如果它真的只是简单的记忆,你很可能会很好,但其他资源会变得棘手。如果驱动程序有错误,套接字和文件句柄可能会泄漏驱动程序中的相关内存。 UI 代码可能会在窗口管理器进程中泄漏。还有很多其他的跨进程资源可能会泄漏。
另外,杀死一个进程会杀死该进程的所有线程,所以任何使用 pthreads 创建的线程都会被杀死。文档中的那一行是指子进程。如果您创建子流程,则需要向这些流程传播信号以通知它们退出。【参考方案2】:
当进程终止时,操作系统会自动释放进程所需的所有“常规”资源(例如内存、套接字、文件句柄)。最重要的例外是共享内存,但如果其他资源不是由操作系统管理,而是由其他进程管理,其他资源也可能会出现问题。
例如,如果您的进程与守护进程或另一个进程(如窗口管理器)通信并分配资源,则在进程终止但未释放它们的情况下是否释放这些资源取决于实现。
【讨论】:
【参考方案3】:我认为这个问题可以换一种方式来回答:pthreads不拥有任何资源,资源归进程所有。 (pthread 可能是资源的“保管人”,例如它分配的内存,但它不是所有者。)当进程终止时,任何仍在运行的 pthread 突然停止,然后进行通常的进程清理。
POSIX 说(对于_Exit()
):
• 通过调用 _Exit() 或 _exit() 终止的线程不应调用它们的取消清理处理程序或每个线程的数据析构函数。
对于exit()
,POSIX 指定了更多的清理——特别是运行所有atexit()
的东西和刷新流等——然后像_Exit()
一样继续。请注意,这不会为任何 pthread 调用任何 pthread 取消清理——系统无法判断任何 pthread 处于什么状态,并且无法确定能够pthread_cancel()
所有 pthread,所以它唯一能做的事情就是就是阻止他们全部死去。
我可以推荐Single UNIX® Specification (POSIX)——就像任何标准一样,它不容易阅读,但值得了解。
【讨论】:
以上是关于进程是不是会在退出时自动清理 pthreads 占用的资源的主要内容,如果未能解决你的问题,请参考以下文章