Stdin和stdout似乎没有被重定向到管道

时间:2017-11-04 18:31:16

标签: python c++ pipe fork

我必须通过fork(),dup2和pipe并行运行一堆程序;
(程序:rgen,A1,A2和驱动程序本身A3) - A3使用cml参数启动并执行rgen(通过fork);
- rgen将stdout传递给A1(通过管道'到'A1');
- A1需要从rgen(通过管道'到A1')获取stdin,处理然后将stdout发送到A2(通过管道'toA2');
- A2需要从A1(从管道'到A2')取stdin;
- A2然后接收该输入并将从A1获得的内容发送到stdout(屏幕),然后等待用户输入A3(通过管道'到A2')或从A1通过管道输入到'A2';
- 然后驱动程序需要从键盘获取stdin并将stdout发送到A2(通过管道'toA2');

问题是管道'toA2'似乎不起作用。我知道A1将正确的输出发送到stdout。我知道A2接收来自stdin的输入。目前A2从键盘接收stdin,如“std :: cin>> use_input”所示,以及当我运行程序时除非我在命令行输入内容,否则它不会做任何其他事情。

终端应该如下所示:

$./A3 -s 5 -n 4 -l 5
V 8
E {<0,2>,<0,3>,<0,4>,<1,3>,<4,7>,<5,2>,<5,6>}
s 2 4
2-0-4

其中“./A3 -s 5 -n 4 -l 5”和“s 2 4”是用户输入到命令行的“V 8”和“E {...}”和“2-0” A2“全部输出到屏幕。

* fyi所有单个程序都运行得很好(可能不是A3,因为它是唯一有潜在问题的程序),我更担心从其他进程获取信息。

我删除了程序中与stdin或stdout无关的所有代码,并将其替换为“...”。如果有必要展示,让我知道,我只是觉得用这种方式阅读会更容易,因为我知道它在我输入之后就有效了。

计划A3(c ++):

int main(int argc, char **argv) {

std::string user_input;
std::vector<pid_t> kids;
pid_t child_pid;
char* empty_arg1[2];
empty_arg1[0] = "A1.py";
empty_arg1[1] = nullptr;
char* empty_arg2[2];
empty_arg2[0] = "A2";
empty_arg2[1] = nullptr;

int toA1[2];
int toA2[1];
pipe(toA1);
pipe(toA2);

child_pid = fork();
//runs rgen; Sends output to 'toA1'
if (child_pid == 0) {

    dup2(toA1[1], STDOUT_FILENO); //Sends stdout to pipe 'toA1'
    close(toA1[0]);
    close(toA1[1]);

    return execv("./rgen", argv);
}

kids.push_back(child_pid);

child_pid = fork();
//runs A1; Sends output to 'toA2'; Gets input from pipe 'toA1'
if (child_pid == 0) {

    dup2(toA1[0], STDIN_FILENO);    //A1 gets stdin from pipe 'toA1'
    close(toA1[0]);
    close(toA1[1]);

    dup2(toA2[1], STDOUT_FILENO); //sends stdout to pipe 'toA2'
    close(toA2[0]);
    close(toA2[1]);

    return execvp("./A1.py", empty_arg1);
}

kids.push_back(child_pid);

child_pid = fork();
//runs A2; Gets input from 'toA2'
if (child_pid == 0) {

    std::string use_input = "blank";
    dup2(toA2[0], STDIN_FILENO); //A2 gets stdin from pipe 'toA2'
    close(toA2[0]);
    close(toA2[1]);
    std::cout << "use_input[1] = " << use_input << std::endl;
    return execv("./A2", empty_arg2);
}

kids.push_back(child_pid);

dup2(toA2[1], STDOUT_FILENO); //Sends output to 'toA2'
close(toA2[0]);
close(toA2[1]);

while (!std::cin.eof()) {

    getline(std::cin, user_input); //Assumes there will be a space after the command
    std::cout << user_input << std::endl;

}

// sends kill signal to all children processes
for (int i = 0; i < kids.size(); i++) {
    int status;
    kill(kids[i], SIGTERM);
    waitpid(kids[i], &status, 0);
}

return 0;
}

程序rgen(c ++):

...

int main(int argc, char** argv) {

........

    // removes pre-existing streets
            std::cout << output << std::endl;
            street_names.pop_back();
        }
    }

........

    //Outputs the 'a' command to add the streets for assignment 1

    std::cout << output << std::endl;
    std::cout << "g" << std::endl;
    sleep(wait_sec);
}

return 0;
}

计划A1(python):

...

def main():

sys.stdout.write("From A1 forked process\n")

.....

        sys.stdout.write("V " + str(len(vertex_list)) + "\n")
        sys.stdout.write(str_edges + "\n")


if __name__ == '__main__':
main()

计划A2(c ++):

int main() {

std::string use_input = "NOPE";
std::cerr << "A2 is running" << std::endl;
std::cin >> use_input;
std::cout << "use_input[2] = " << use_input << std::endl;

while (!std::cin.eof()) {

    getline(std::cin, user_input); //Assumes there will be a space after the command

    std::istringstream iss(user_input);
    iss >> command;
    if (command == 'V') {

       ....

    }
    else if (command == 'E') {

        ...         

        iss >> edges;
        std::cout << "V " << num_vert << std::endl;
        std::cout << "E " << edges << std::endl;

        ...

    }
    else if (command == 's') {

        ...

        iss >> str_vert >> end_vert;

         ....

            std::cout << path;
            std::cout << std::endl;
    }
    else {
        std::cerr << "Error: Invalid command[a2]" << std::endl;
    }
}
return 0;
}

0 个答案:

没有答案