GNU/Linux >> Linux の 問題 >  >> Linux

パイプ、dup2、および exec()

親プロセスと子プロセスの両方ですべてのパイプ記述子を閉じる必要があります (子プロセスで複製した後)。あなたのコードの主な問題は、 wc まだライターが存在するため、プロセスは終了しません (親プロセスが書き込み終了を閉じていないため)。以下に変更点を示します。 waitpid も追加しました 親プロセスで wc を待つ

pid_t pid;
int fd[2];

pipe(fd);
pid = fork();

if(pid==0)
{
    dup2(fd[WRITE_END], STDOUT_FILENO);
    close(fd[READ_END]);
    close(fd[WRITE_END]);
    execlp(firstcmd, firstcmd, frsarg, (char*) NULL);
    fprintf(stderr, "Failed to execute '%s'\n", firstcmd);
    exit(1);
}
else
{ 
    pid=fork();

    if(pid==0)
    {
        dup2(fd[READ_END], STDIN_FILENO);
        close(fd[WRITE_END]);
        close(fd[READ_END]);
        execlp(scmd, scmd, secarg,(char*) NULL);
        fprintf(stderr, "Failed to execute '%s'\n", scmd);
        exit(1);
    }
    else
    {
        int status;
        close(fd[READ_END]);
        close(fd[WRITE_END]);
        waitpid(pid, &status, 0);
    }
}

うーん、十分に近い。 fork 後のいくつかのファイル記述子で close を処理し損ねています。

ここにいくつかの参照があります:

<オール>
  • パイプについて、http://unixwiz.net/techtips/remap-pipe-fds.html
  • ファイル記述子について、http://www.usna.edu/Users/cs/aviv/classes/ic221/s14/lec/09/lec.html
  • これが私のコードです:

    #include  <fcntl.h>                              //
    #include  <stdio.h>                              //
    #include  <stdlib.h>                             //
    #include  <string.h>                             //
    #include  <sys/types.h>                          //
    #include  <sys/wait.h>                           //
    #include  <sys/stat.h>                           //
    #include  <termios.h>                            //
    #include  <unistd.h>                             //
                                                     //
    #define INPUT_END 1                              // INPUT_END means where the pipe takes input
    #define OUTPUT_END 0                             // OUTPUT_END means where the pipe produces output
                                                     //
    int main(int argc, char* argv[])                 //
    {                                                //
        pid_t pid1;                                  // [STDIN -> terminal_input, STDOUT -> terminal_output]                       (of the parent process)
        pid_t pid2;                                  //
        int fd[2];                                   //
                                                     //
        pipe(fd);                                    // [STDIN -> terminal_input, STDOUT -> terminal_output, fd[0] -> pipe_input, fd[1] -> pipe_output]
        pid1 = fork();                               //
                                                     //
        if(pid1==0)                                  //
        {                                            // I am going to be the wc process (i.e. taking input from the pipe)
            close(fd[INPUT_END]);                    // [STDIN -> terminal_input, STDOUT -> terminal_output, fd[1] -> pipe_output] (of the WC process)
            dup2(fd[OUTPUT_END], STDIN_FILENO);      // [STDIN -> pipe_output, STDOUT -> terminal_output, fd[1] -> pipe_output]    (of the WC process)
            close(fd[OUTPUT_END]);                   // [STDIN -> pipe_output, STDOUT -> terminal_output]                          (of the WC process)
            execlp("wc", "wc", "-l",(char*) NULL);   //
        }                                            //
        else                                         //
        {                                            //
            pid2=fork();                             //
                                                     //
            if(pid2==0)                              //
            {                                        // I am going to be the ls process (i.e. producing output to the pipe)
                close(fd[OUTPUT_END]);               // [STDIN -> terminal_input, STDOUT -> terminal_output, fd[0] -> pipe_input] (of the ls process)
                dup2(fd[INPUT_END], STDOUT_FILENO);  // [STDIN -> terminal_input, STDOUT -> pipe_input, fd[0] -> pipe_input]      (of the ls process)
                close(fd[INPUT_END]);                // [STDIN -> terminal_input, STDOUT -> pipe_input]                           (of the ls process)
                execlp("ls","ls","-l",(char*) NULL); //
            }                                        //
                                                     //
            close(fd[OUTPUT_END]);                   // [STDIN -> terminal_input, STDOUT -> terminal_output, fd[0] -> pipe_input] (of the parent process)
            close(fd[INPUT_END]);                    // [STDIN -> terminal_input, STDOUT -> terminal_output]                      (of the parent process)
            waitpid(-1, NULL, 0);                    // As the parent process - we wait for a process to die (-1) means I don't care which one - it could be either ls or wc
            waitpid(-1, NULL, 0);                    // As the parent process - we wait for the another process to die.
                                                     // At this point we can safely assume both process are completed
        }                                            //
    }                                                //
    

    Linux
    1. [[$ a ==Z*]]と[$a==Z *]の違いは?

    2. PおよびEは、Execファミリのコールで何を示しますか?

    3. Grep And Tail -f?

    1. PthreadとVfork?

    2. Linux のパイプとリダイレクト - 解説!

    3. ラズベリーパイ4とカーリー

    1. Linuxでパイプと名前付きパイプを使用する方法(例付き)

    2. Ls *、Ls**およびLs***の結果?

    3. fork()、vfork()、exec()、clone()の違い