0

我正在编写一个 C 程序,它使用多个管道运行以下 Linux 命令:

猫 myfile1.txt | egrep 计算 | wc -l > 我的文件

我的代码如下:

    int p_fd[2];
    pid_t childpid, waitReturn;
    int pid=1;
    int status, i;

    pipe(p_fd);

    for( i = 1 ; i < 3 ; i++ )
        if( childpid = fork() )
            break;
        else
            pid++;

    while( childpid != ( waitReturn = wait( &status ) ) )
        if( ( waitReturn == -1 ) && ( errno != EINTR ) )
            break;

    if ( childpid > 0 && pid == 1 ){
        printf("%d\n", pid);
        int fd;
        if ( ( fd= open("myfile", O_CREAT|O_RDWR|O_TRUNC, 00644)) == -1 )
        {
                printf("Error: Cannot open file in open()\n");
                exit(1);
        }
        close(0);
        dup(p_fd[0]);
        close(1);
        dup(fd);
        close(p_fd[0]);
        close(p_fd[1]);
        close(fd);
        execl("/bin/wc", "wc", "-l", NULL);
    }else if( childpid > 0 && pid == 2 ){
        printf("%d\n", pid);
        close(0);
        dup(p_fd[0]);
        close(1);
        dup(p_fd[1]);
        close(p_fd[0]);
        close(p_fd[1]);

        execl("/bin/egrep", "egrep", "Computing", NULL);

    }else if( childpid == 0 && pid == 3 ){
        printf("%d\n", pid);
        close(1);
        dup(p_fd[1]);
        close(p_fd[0]);
        close(p_fd[1]);

        execl("/bin/cat", "cat", "myfile1.txt", NULL);
    }   

    return 0;

但是,当我的程序到达“execl(”/bin/egrep”、“egrep”、“Computing”、NULL);”时,我的程序挂起,它在第二个孩子中以 pid 2 调用。

我不知道我的程序挂在那里的原因;是关于管道的死锁吗?

任何人都可以帮助我修改上述程序,以便它可以给我想要的结果吗?

4

1 回答 1

1

类似下面的伪代码怎么样:

create_pipe_between_cat_and_egrep();
create_pipe_between_egrep_and_wc();
create_destination_file();

if (fork() == 0)
{
    /* Process for cat */
    setup_pipe_stdout_for_cat();
    execl("cat", "cat", "arguments");
}

if (fork() == 0)
{
    /* process for egrep */
    setup_pipe_stdin_stdout_for_egrep();
    execl("egrep", "egrep", "arguments");
}

if (fork() == 0)
{
    /* process for wc */
    setup_pipe_stdin_for_wc();
    setup_file_stdout_for_wc();
    execl("wc", "wc", "arguments");
}

wait_for_all_three_child_processes_to_finish();

使用上面三个不同的块而不是循环更容易遵循流程。

大部分代码可以放在通用函数中,例如为子进程设置stdin/描述符。stdout

于 2013-10-17T09:51:11.883 回答