1

リストを頭からつま先まで調べることができるように、(または)を介してターミナルでページングできる長いリストを出力する小さなプログラムを作成したいと思います...moreless

プログラム:

  • forkmoreプログラムが実行される子プロセスから離れている
  • 親プロセスでは、リストが出力されます
  • 親によってpipe印刷されたリストがプログラムのstdoutmorestdin

コード:

int main(int argc, char *argv[])
{
    int pager, status;
    int pipes[2];

    pipe(pipes);

    pager = fork();

    if (pager == 0) { // child

        dup2(pipes[0], 0);
        close(pipes[1]);
        char *args[] = {"more", NULL}; 
        execvp(args[0], args);

    } else { // parent

        dup2(pipes[1], 1);

        int x;
        for (x = 0; x < 500; x++) {
            printf("Hello World! %d\n", x);
        }  

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

        wait(&status);
    } 

    return 0;
}

私はこれをほとんどの部分で機能させています:

  • 「Hello World!...」メッセージの長いリストが a でクリップされた端末に出力される--More--ので、基本的なパイプのセットアップが機能していることがわかります。
  • [q]リスト全体の印刷が終了する前に押すと(moreプロセスを終了する)、プログラム(親/子)が期待どおりに終了します

私が抱えている唯一の問題は、[space]or[return]を押し続けmoreてリストの最後 (500 番目の "Hello World!..." メッセージ) に到達すると、端末がハングすることです。押し[q]ても反応がありません (出なければ [ctrl+c]なりません)。

親プロセスが でスタックしていwaitます。 親のmore両方のパイプを閉じたにもかかわらず、プロセスが終了しません

4

1 に答える 1

1

あなたのコードpipe[0]では、あなたが子供に書いている記述子ではないものを閉じています。パイプが終了しdup2(pipes[1], 1)たことを子供に伝えるために、書き込み先のパイプを閉じる必要があります。

close(1);

もちろん、標準出力を使用してプロセスを続行する場合は、元の出力を復元する必要があります。これは現在閉じられているためです。

于 2014-01-03T12:11:45.857 に答える