2014-04-27 4 views
1

У меня есть две программы на C++: Program1 и Program2. Я хочу, чтобы программа1 запускала свой алгоритм, чтобы вычислить все, что ему нужно, и затем передать всю эту рассчитанную информацию в Program2, чтобы она могла запускать свой алгоритм, используя вывод Program1.Команды подпроцесса в C++

Было бы неплохо, если бы я мог просто передать информацию и закрыть Program1, не дожидаясь завершения программы Program2. Это будет что-то вроде subprocess.call() в python.

+0

Вы можете найти http://www.highscore.de/boost/process/ полезным. Не могу сказать много об этом, хотя я никогда не использовал его. Если решение не должно быть переносимым, может потребоваться старая «fork» (или даже «система»). –

+0

Функции, которые могут оказаться полезными: 'fork',' exec', 'dup2',' write', 'read'. – Till

+0

Используйте ['popen (3)'] (http://linux.die.net/man/3/popen), похоже, что это подойдет вашим потребностям. Это намного проще в использовании, чем комбинация 'pipe/fork/dup2/exec'. –

ответ

1

Вы хотите сделать что-то вдоль линий этого:

#include <unistd.h> 

int main() { 
    // Do stuff for program1 
    int pipefds[2]; 
    if (pipe (pipefds)) 
    throw 1; 
    // Use ``write'' to send binary data to pipefds[0] 
    dup2 (pipefds[1], 0); 
    execl (/* Put the program2 arguments you want here. */); 
    return 1; 
} 

С этим, все, что вам нужно, это иметь program2 прочитать все необходимые данные из стандартного ввода, и вы сделали.

+0

Что делает 'dup2 (pipefds [1], 0)' делать точно ...? – Richard

1

Для эмуляции subprocess.check_call("Program1 | Program2", shell=True) Python вызов, вы можете использовать system(3) in C:

/** $ gcc simple-pipe-system.c && ./a.out */ 
#include <stdlib.h> 

int main(void) { 
    return system("Program1 | Program2"); 
} 

Вот как эмулировать Program1 | Program2 трубопровода, используя низкий уровень pipe(2)/fork(2)/execlp(2) in C для сравнения:

/** $ gcc simple-pipe.c && ./a.out */ 
#include <sys/types.h> /* pid_t */ 
#include <unistd.h> 

int main(void) { 
    int fd[2]; /* pipe ends */ 
    pid_t pid = -1; 

    if (pipe(fd) == -1) 
    Report_error_and_exit("pipe"); 

    if ((pid = fork()) == -1) 
    Report_error_and_exit("fork"); 
    else if (pid == 0) { 
    /* child: run Program1, redirecting stdout to the pipe */ 
    is_child = 1; 
    Close(fd[0]); /* close unused read end of the pipe */ 

    /* redirect stdout */ 
    Redirect(fd[1], STDOUT_FILENO); 

    /* run Program1 with redirected stdout */ 
    execlp("Program1", "Program1", NULL); 
    Report_error_and_exit("execlp"); 
    } 

    /* parent: run Program2, redirecting stdin to the pipe */ 
    Close(fd[1]); /* close unused write end of the pipe */ 

    /* redirect stdin */ 
    Redirect(fd[0], STDIN_FILENO); 
    /* run Program2 with redirected stdin */ 
    execlp("Program2", "Program2", NULL); 
    Report_error_and_exit("execlp"); 
} 

где Report_error_and_exit, Close, Перенаправление может быть определяется как:

#include <errno.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 

#include <unistd.h> 

#define Close(FD) do {           \ 
    const int Close_fd = (FD);         \ 
    if (close(Close_fd) == -1)         \ 
     fprintf(stderr, "%s:%d: close(" #FD ") %d: %s\n",   \ 
      __FILE__, __LINE__, Close_fd, strerror(errno));  \ 
    }while(0) 

#define Report_error_and_exit(msg) do {      \ 
    fprintf(stderr, "%s:%d: %s: %s\n", __FILE__, __LINE__, \ 
     (msg), strerror(errno));        \ 
    (is_child ? _exit : exit)(EXIT_FAILURE);     \ 
    } while(0) 
static int is_child = 0; 

#define Redirect(FROM, TO) do {   \ 
    const int from = (FROM);    \ 
    const int to = (TO);     \ 
    if (from != to) {      \ 
     if (dup2(from, to) == -1)   \ 
     Report_error_and_exit("dup2");  \ 
     else         \ 
     Close(from);      \ 
    }          \ 
    } while(0) 
Смежные вопросы