【问题标题】:How can child process tell its parent to create a new child?子进程如何告诉其父进程创建一个新子进程?
【发布时间】:2016-02-02 05:39:26
【问题描述】:

亲爱的,

我正在使用 C++ 编写网络服务器应用程序。

当启动时,它会创建一个监听器套接字和用户定义数量的子进程(工作者),每个子进程(使用 kqueue、epoll 等)监视监听器以获取新的客户端连接,accept()'ing 他们并创建处理响应处理的线程。一旦工作子进程响应了用户定义数量的客户端请求,它必须告诉父进程创建一个新的子进程,等待所有线程完成然后退出。

我的问题是:如果我的父进程中有一个创建子进程的函数 (create_child()),我是否可以从子进程中调用它并获得父进程的新子进程(期望的结果),或者将它创造了一个孩子的孩子?前任。 (伪代码):

void create_child() {
    //create child process
}

int main()
{
    //do things

    if(fork() == 0) {
        //do things

        create_child(); //is result a child of parent or child of child?
    }
}

我不喜欢使用管道,我想避免它的开销,但请告诉我它是否是唯一的解决方案。我目前没有 Linux 系统来编写一个简单的程序并测试会发生什么,但在我的搜索中,我在某处读到它将创建一个子进程的子进程。那么,如何从另一个子节点中创建父节点的子节点

如果变得难以理解,我很抱歉,写这个问题时我有点困。提前感谢您的帮助。

【问题讨论】:

  • 如果 fork() 返回 0,则当您执行 create_child 函数时,您已经处于子进程中。该进程是调用 fork 的进程的子进程。原来的父进程没有特殊意义,并且不被fork跟踪。
  • 父进程还会做什么?为什么不让父进程监视子进程的终止,并创建一个新的子进程来替换它?
  • @Donnie,我知道。我想要的是某种方式,从孩子内部(在 fork() == 0 之后)告诉父母创建一个新孩子。
  • 你想要的叫做进程间通信
  • 您需要使用某种 IPC 来要求父代为您分叉。如果管道太重并且您不需要大量通信,则可以使用其他 IPC 机制(例如信号量)

标签: c++ c fork child-process


【解决方案1】:

一般来说,当你做forks,想要父子进程之间(或者一般的进程之间,想想看)之间的通信,你可以使用pipe

    #include <stdio.h>
    #include <unistd.h>
    #include <sys/types.h>

    main()
    {
            int     fd[2];
            pid_t   childpid;

            pipe(fd);

            if((childpid = fork()) == -1)
            {
                    perror("fork");
                    exit(1);
            }
            .
            .
    }

孩子和父母可以使用(惊喜!)readwrite 系统调用,使用fds 进行读写。 (如果通信应该是一种方式,那么fds 应该关闭一些,顺便说一句。)

一旦进行通信,您就可以设计任何您希望子进程与父进程通信的协议,包括跨越其他进程。

【讨论】:

  • 这似乎解决了我的问题,但我想避免管道以摆脱额外的开销并为操作系统工作(将需要 kqueue/epoll 监控管道,我读了一些关于系统需要保留管道的内容同步性...),因为性能是此应用程序的关键点...
  • 我想你会感到惊讶。配置文件以查看是否添加了管道调用,以实际启动一个新进程 - 实际上会有所作为。我愿意和你打赌一杯咖啡(不过,我不知道该怎么做)——它不会。 :-) 不要忘记 - 过早的优化是万恶之源。
【解决方案2】:

回答第一个问题:如果你从一个孩子那里分叉,那么这个孩子就有一个孩子。您最初的父进程是最后一个进程的祖父进程。

更有趣的是,如果第一个孩子终止,而第二个孩子仍在运行——这就是您当前设计中会发生的情况——第二个孩子成为孤儿并附加到 init。不允许任何进程没有父进程。最初的父进程无法监控这个刚刚被init收养的被遗弃的孙子。

回答第二个问题:你不能。

您可能应该从父级内部监视子级。使用您当前的设计,如果孩子在告诉父母更换它之前就死了怎么办?还是在它自己替换之前?

这可能是一个起点:

for(int i=0;i<10;++i)
  create_process();
for(;;) {
  int status;
  wait( &status );
  create_process();
}

【讨论】:

  • 从父进程中监视子进程(以便他们退出)并不能解决整个问题,因为子进程甚至会在它退出之前告诉父进程创建一个新子进程。无论如何,谢谢你,你的回答让我想起了添加对工人数量的监控 accept()'ing 请求,因为在告诉父母替换它之前,有些人可能会因为未捕获的异常或其他原因意外退出。
猜你喜欢
  • 2017-08-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-07-24
  • 1970-01-01
  • 2014-05-11
  • 1970-01-01
相关资源
最近更新 更多