0

ls | wc | wcのようなものを実行するacプログラムを書き直そうとしています。すでに、ls | wcに対して実行しました。正常に動作しましたが、プログラムが示された行の子で停止する理由がわかりません。助けてください!

int main (void)
{
    pid_t pid_fils, pid_pfils;

    int fd[2], fd2[2];

    if(pipe(fd)==-1 || pipe(fd2)==-1)
    {
        printf("pipe failed!");
        return 1;
    }

    printf("program started\n");
    pid_fils=fork();
    if(pid_fils==0)
    {
        pid_pfils=fork();
        if(pid_pfils==0)
        {
            //action3
            printf("I am the grandson\n");
            close(fd[0]);//close read side
            dup2(fd[1],1);//connect write with stdout
            close(fd[1]);//close write side
            execlp("ls","ls",(char*)0);
            //execvp("ls",argv3);
            return 0;/*actions grandson*/
        }
        else
        {
            //action2
            printf("I am the son\n");
            wait();
            printf("son, wait ok\n");
            >close(fd[1]);  //close read side
            >dup2(fd[0],0); //connect write with stdin
            >close(fd[0]);  //close read side

            ///////pipe2////
           > close(fd2[0]);  //close read side
            >dup2(fd2[1],1); //connect write with stdout/*it stops here -can't display "ok!"*/
            printf("ok!\n");    
            >close(fd2[1]);  //close write side

            execlp("wc","wc",(char*)0);
            printf("error exec returned!\n");    
            return 0;
        }
    }
    else
    {
        ///action1
        printf("I am the parent\n");
        wait();
        printf("parent,wait ok\n");
        close(fd2[1]);  //close write side, 
        dup2(fd2[0],0); //connect read with stdin
        close(fd2[0]);  //close read side
        execlp("wc","wc",(char*)0);
        return 0;/*the parent*/
    }
    return 1;
}
4

2 に答える 2

3

未使用の記述子はすべて閉じてください。あなたの場合、最も簡単な解決策は、pipe(fd)の作成を最初のifブロック(最初のサブプロセス)に移動することです。問題は、プロセスがパイプに書き込む可能性がある限り、リーダーがEOFを取得しないため、終了しないことです。

if(pipe(fd2)==-1)
{
    printf("pipe failed!");
    return 1;
}

printf("program started\n");
pid_fils=fork();
if(pid_fils==0)
{
    if(pipe(fd)==-1)
    {
        printf("pipe failed!");
        return 1;
    }
    pid_pfils=fork();

また、待機呼び出しを再検討することをお勧めします。それらで何をしようとしているのかわからないが、リーダーがまだ開始されていないため、「ls」プロセスが出力でブロックすることは望ましくありません。

于 2013-01-12T00:16:03.580 に答える
1
dup2(fd2[1],1);

上記の行は、最初に記述子1でファイルを閉じてから、記述子をfd2[1]から1に複製します。

1はstdoutです。その呼び出しがstdoutを閉じたことを意味します。

printfはstdoutに出力します。つまり、printfは1に出力され、パイプfd2に割り当てられます。

だからあなたのOKは画面上ではなくパイプに入った。

試す

        //action2
        printf("I am the son\n");
        wait();
        printf("son, wait ok\n");
        close(fd[1]);  //close read side
        dup2(fd[0],0); //connect write with stdin
        close(fd[0]);  //close read side

        ///////pipe2////
        int my_terminal_out = dup(1);
        close(fd2[0]);  //close read side
        dup2(fd2[1],1); //connect write with stdout/*it stops here -can't display "ok!"*/
        fprintf(my_terminal_out, "ok!\n");    
        close(fd2[1]);  //close write side

未検証。また、同様のミスステップについてコードの残りの部分をテストする必要があります。

+DrCが言ったこと。

于 2013-01-12T00:17:29.763 に答える