首页 > 解决方案 > 如何守护一个继承所有父线程的进程?

问题描述

我有一个创建多个线程并创建套接字的进程。现在我想通过调用 fork() 创建一个守护进程并退出父进程。但是当父进程被杀死时,父进程创建的线程会退出。有没有办法可以将这些线程和套接字继承给子进程?(代码在 CPP 中运行)

标签: operating-systempthreadsforkdaemon

解决方案


但是当父进程被杀死时,父进程创建的线程会退出。

不完全是。父母的线程不受影响,孩子只得到调用的线程fork()。这与孩子获得其他线程并随后终止它们不同。特别是,在子进程中不会调用可能已注册的取消处理程序或退出处理程序,这可能会使互斥锁和其他同步对象处于不可用和不可恢复的状态。清理这样的混乱是分叉处理程序的预期目的,但是正确使用它们很棘手,并且必须在整个过程中始终如一地使用它们才能有效。

我有办法将这些线程和socker继承到子进程吗?

子进程自动继承其父进程的打开文件描述符,因此无需对套接字进行任何特殊处理。但是其他线程呢?不。

POSIX 文档对fork所有这些都是明确的:

新进程(子进程)应是调用进程(父进程)的精确副本,以下详述除外:

[...]

  • 子进程应拥有自己的父文件描述符副本。每个子文件描述符都应与父文件描述符对应的打开文件描述相同。

[...]

  • 应使用单个线程创建进程。如果多线程进程调用fork(),新进程应包含调用线程及其整个地址空间的副本,可能包括互斥锁和其他资源的状态。因此,为避免错误,子进程只能执行异步信号安全操作,直到调用其中一个 exec 函数。

    当应用程序fork()从信号处理程序和任何注册的分叉处理程序pthread_atfork()调用一个非异步信号安全的函数时,行为是未定义的。

如果分叉的目标是与原始会话和父级分离,以便在后台作为守护进程运行,那么最好的办法是让初始线程在启动时立即执行此操作,然后再创建任何其他线程或打开任何套接字.


推荐阅读