1

私はこの方法を持っています:

int build_pipe_and_call(char **argv1, std::string cmd1, char **argv2, std::string cmd2, int conc) {
    std::cout << "Building Pipe...\ncmd1: " << cmd1 << "\n cmd2: " << cmd2 << "\n";
    int *pipefd = new int[2];
    if (pipe(pipefd) < 0) {
        std::cerr << "There was an error setting up the pipe.\n";
        return -1;
    }
    pid_t cpid1 = fork();
    std::cout << "First process forked, cpid: " << cpid1 << " - Process " << getpid() << "\n";
    switch (cpid1) {
        case -1:
            std::cerr << "There was an error forking the process.\n";
            return -1;
            break;
        case 0: // this is the part that isn't executing
            std::cout << "Dup2 return: " << dup2(pipefd[1], 1) << "\n";
            std::cout << "Process " << getpid() << " duped and about to exec.\n";
            execvp(cmd1.c_str(), argv1);
            std::cout << "Process " << getpid() << " about to exit.\n";
            _exit(0);
            break;
        default:
            pid_t cpid2 = fork();
            switch (cpid2) {
                case -1:
                    std::cerr << "There was an error forking the process.\n";
                    return -1;
                    break;
                case 0:
                    dup2(pipefd[0], 0);
                    std::cout << "Process " << getpid() << " duped and about to exec.\n";
                    execvp(cmd2.c_str(), argv2);
                    _exit(0);
                    break;
                default:
                    if (conc) {

                    } else {
                        int status1, status2;
                        std::cout << "Process " << getpid() << " about to wait.\n";
                        waitpid(cpid1, &status1, 0);
                        waitpid(cpid2, &status2, 0);
                    }
                    break;
            }
        }
    delete[] pipefd;
    return 0;
}

デバッグのためだけに print ステートメントを追加しました。ただし、このメソッドを実行すると、これが出力されます。

Building Pipe...
cmd1: cat
cmd2: wc
First process forked, cpid: 1454 - Process 1453
First process forked, cpid: 0 - Process 1454
Process 1453 about to wait.
Process 1455 duped and about to exec.

最初に fork されたプロセス 1454 は、作成直後にメッセージを出力します。ただし、switch ステートメントからのメッセージを出力したり、指定されたプログラム (この場合は cat) を実行したりすることはありません。プロセスはゾンビとしてぶらぶらしません。単に消えます。その結果、2 番目の子プロセスがハングアップし、実際には何もしません。

(また、追加するために、適切なエラー処理をすべてまだ追加していないことを認識しています。関数はまだ完全ではありません)。

4

2 に答える 2

1

パイプラインは EOF を検出すると終了します。そのためには、不要な記述子を一度ダンプしたら閉じる必要があります (子と親で):

close(pipefd[0]);
close(pipefd[1]);

また、常に の戻り値を確認してくださいexecvp。argv にエラーがある可能性があります。

if (execvp(cmd1.c_str(), argv1) == -1) {
    // check errno here
}

さらに、必ず最後の要素としてnullptrで argv を終了し、 argv[0]はコマンド自体である必要があります。プロトタイプ:

int build_pipe_and_call(char **argv1, std::string cmd1, char **argv2, std::string cmd2, int conc)

...最初の要素( argv[0] = cmd1 )を提供していないと思います。argvにある場合、機能するためにその追加の値 ( cmdX ) を指定する必要はありません。build_pipe_and_call

うまくいけばexecvp、プログラムの後続のコードに到達することはないので、期待どおりにメッセージが表示されないことに注意してください。

execvp(cmd1.c_str(), argv1);
std::cout << "Process " << getpid() << " about to exit.\n"; // if execvp didn't fail, it's never reached

また、@larpicoが答えたように、一度ダンプしたらstd::coutを使用するように注意してください

于 2014-10-06T02:59:39.327 に答える