如何守护继承所有父线程的进程?

问题描述

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

解决方法

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

不完全是。父级的线程不受影响,子级仅获得名为fork()的线程。这与孩子获得其他线程,然后终止它们是不同的。特别是,没有在子级中调用可能已由它们注册的取消处理程序或退出处理程序,这可能会使互斥体和其他同步对象处于无法使用和不可恢复的状态。清理此类混乱是 fork 处理程序的预期目的,但是正确使用它们很棘手,必须在整个过程中始终使用它们才能有效。

我有一种方法可以继承那些线程并将其存储到子进程吗?

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

The POSIX documentation for fork对于所有这些都是明确的:

新进程(子进程)应为调用的精确副本 流程(父流程),具体如下:

[...]

  • 子进程应具有其自己的父文件描述符的副本。孩子的每个文件描述符都应引用 与相同的打开文件描述相同的文件描述符 父母。

[...]

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

    当应用程序从信号处理程序调用{​​{1}}时,并且fork()注册的任何fork处理程序都调用一个函数, 不是异步信号安全的,其行为是不确定的。

如果分叉的目的是与原始会话和父进程分离,以便在后台作为守护程序在后台运行,那么最好的选择是让初始线程在启动后立即执行此操作,然后再创建任何其他线程或打开任何插座。