我正在使用boost::process::child生成新进程。
我正在启动的进程的启动时间不是即时的,因此我必须等待一段时间才能完全初始化它。

auto is_ptr = std::make_shared<bp::ipstream>();
auto child_pr = std::make_shared<bp::child>(executable, args, bp::std_out > *is_ptr);
m_childs[port] = {child_pr, is_ptr};

std::string line;
while (child_pr->running() && std::getline(*is_ptr, line)) {
    std::cerr <<"SI: \t" << line << std::endl;
    if( 0 == line.compare(0, string_to_find.size(), string_to_find)){
        break;
    }
}
...

在这个周期之后,我不再需要ipstream了。有什么办法可以将其与子进程分离?

最佳答案

由于您要求提供答案,因此我将在此处添加一些其他信息,尽管我不确定它是否可以完全回答您的问题。

假设目标平台是Linux,则一旦父进​​程中的ipstream被销毁,这实际上意味着父进程和子进程之间的关联管道的文件描述符在父进程中已关闭。在父进程关闭管道的读取端之后,一旦子进程将其写入管道,就会为该子进程生成SIGPIPE,如果不采取其他措施,它将导致该子进程终止。

为防止这种情况,一种选择是忽略子级中的SIGPIPE。现在,在写入该管道时,这将在子进程中导致错误。这取决于子进程的执行原因。您的解决方案是忽略SIGPIPE,并在子进程无法成功写入数据后对其采取措施,以防止浪费大量CPU周期。

要在较低级别进行试验,可以使用以下程序。只要成功,它将派生一个子进程,该子进程将继续写入某些输出。父进程一旦从中读取了一些数据,就会关闭相应的管道。

程序的行为因子进程中SIGPIPE的处理方式而异。如果忽略它,则子进程中的write()将失败,并且子进程将以非零的退出代码退出。如果SIGPIPE不被忽略,则子进程由操作系统终止。父进程将告诉您子进程中发生了什么。

#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>

int main(int argc, char** argv)
{
    int pipe_fds[2];
    if (pipe(pipe_fds) < 0) {
        perror("pipe");
        exit(1);
    }

    pid_t pid;
    if ((pid = fork()) < 0) {
        perror("fork");
        exit(1);
    }

    if (pid == 0)
    {
        close(pipe_fds[0]); /* close read-end in the child */

        /* Uncomment the following line, and the child will terminate as soon
           as the parent closes the read end of the pipe...This is here merely
           for illustrative purposes, production code should use either
           sigaction() or pthreads related signal functionality in case of a
           multi-threaded program. */

        /* signal(SIGPIPE, SIG_IGN); */

        /* Child process, start writing to the write-end of the pipe. */
        const char message[] = "Hello world!\n";
        while (write(pipe_fds[1], message, strlen(message)) >= 0);

        exit(1);
    }

    close(pipe_fds[1]);
    char buf[256];
    ssize_t count;
    while ((count = read(pipe_fds[0], buf, sizeof(buf) - 1)) == 0);
    if (count < 0) {
        perror("read");
        exit(1);
    }

    buf[count] = '\0';
    printf("%s", buf);

    /* Close read-end in the parent, this will trigger SIGPIPE in the child
       once the child writes to the pipe. */
    close(pipe_fds[0]);

    int stat;
    if (waitpid(pid, &stat, 0) < 0) {
        perror("waitpid");
        exit(1);
    }

    if (WIFSIGNALED(stat) && WTERMSIG(stat) == SIGPIPE) {
        printf("\nChild terminated by SIGPIPE\n");
    }
    if (WIFEXITED(stat)) {
        printf("\nChild exited with exit code %d\n", WEXITSTATUS(stat));
    }

    exit(0);
}

关于c++ - 经过一段时间后,是否有办法从流程中分离流程?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/58589288/

10-09 22:45