C ++ захват раздвоенного ребенка cout - PullRequest
0 голосов
/ 29 ноября 2018

У меня есть следующий фрагмент кода:

stringstream userOut;
streambuf* old = cout.rdbuf(userOut.rdbuf());

pid_t pid;

if (!(pid = fork())) {

    cout << "hello from child!" << endl;
    exit(0);


} else {
    int status;

    // wait for child to finish
    wait(&status);

    // give cout old buffer back
    cout.rdbuf(old);

    // prints nothing!
    cout << "child content: " << userOut.str() << endl;
}

Я хочу иметь возможность перехватывать и перенаправлять cout из дочернего процесса для использования в родительском процессе, но пока перенаправленный вывод всегда пуст,Что может быть причиной этого и есть ли доступные решения?

1 Ответ

0 голосов
/ 29 ноября 2018

Как уже упоминалось в комментариях, разветвленный процесс получает копию потока.Так что его запись в копию выходного потока.

Обычно вы хотите использовать каналы для такого рода проблем.Если вы обратитесь к man 2 pipe, вы увидите этот пример в конце:

Следующая программа создает канал, а затем fork (2) для создания дочернего процесса;дочерний объект наследует дубликат набора файловых дескрипторов, которые ссылаются на один и тот же канал.После fork (2) каждый процесс закрывает файловые дескрипторы, которые ему не нужны для канала (см. Pipe (7)).Затем родительский элемент записывает строку, содержащуюся в аргументе командной строки программы, в канал, а дочерний элемент читает эту строку по байтам из канала и выводит ее на стандартный вывод.

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

   int
   main(int argc, char *argv[])
   {
       int pipefd[2];
       pid_t cpid;
       char buf;

       if (argc != 2) {
           fprintf(stderr, "Usage: %s <string>\n", argv[0]);
           exit(EXIT_FAILURE);
       }

       if (pipe(pipefd) == -1) {
           perror("pipe");
           exit(EXIT_FAILURE);
       }

       cpid = fork();
       if (cpid == -1) {
           perror("fork");
           exit(EXIT_FAILURE);
       }

       if (cpid == 0) {    /* Child reads from pipe */
           close(pipefd[1]);          /* Close unused write end */

           while (read(pipefd[0], &buf, 1) > 0)
               write(STDOUT_FILENO, &buf, 1);

           write(STDOUT_FILENO, "\n", 1);
           close(pipefd[0]);
           _exit(EXIT_SUCCESS);

       } else {            /* Parent writes argv[1] to pipe */
           close(pipefd[0]);          /* Close unused read end */
           write(pipefd[1], argv[1], strlen(argv[1]));
           close(pipefd[1]);          /* Reader will see EOF */
           wait(NULL);                /* Wait for child */
           exit(EXIT_SUCCESS);
       }
   }
...