【问题标题】:How to daemonize a process that inherits all parents threads?如何守护一个继承所有父线程的进程?
【发布时间】:2021-02-11 16:31:01
【问题描述】:

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

【问题讨论】:

    标签: operating-system pthreads fork daemon


    【解决方案1】:

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

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

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

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

    The POSIX documentation for fork 明确说明了这一切:

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

    [...]

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

    [...]

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

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-07-20
      • 1970-01-01
      • 2011-07-13
      • 1970-01-01
      • 2021-12-31
      相关资源
      最近更新 更多