fork()和pipe()的小问题

时间:2009-12-24 15:09:36

标签: c unix posix pipe fork

我正在编写一个实现管道的小程序,就像它们在shell中工作一样。 即:

ls -hal | sort | grep p | wc

它工作正常,在一行上的次要问题,当CMD_NO = n时,CMD_NO的比较大不起作用,但是i!=(CMD_NO-1)。我试图弄清楚为什么在这种特殊情况下(该行在代码中被命名为TROUBLED LINE)这些语句不等效。非常感谢。

#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>

#define READ_END 0
#define WRITE_END 1
#define CMDS_NO 5

int main (int argc, char **argv) 
{
    pid_t pid;
    int new_fds[2];
    int old_fds[2];

    char *array[CMDS_NO];
    char *param[CMDS_NO];

    array[0]="ls";
    array[1]="sort";
    array[2]="grep";
    array[3]="grep";
    array[4]="wc";

    param[0]="-hal";
    param[1]=NULL;
    param[2]="p";
    param[3]="out";
    param[4]=NULL;


    for (int i=0; i<CMDS_NO; i++) {

        if (i<CMDS_NO) //if there is a next command 
           pipe(new_fds);

        pid=fork();

        if (pid==0) { //if child
            if (i!=0) { //if there is ap revoius commmand
                dup2(old_fds[0], 0);
                close(old_fds[0]);
                close(old_fds[1]);
            }

            if (i!=(CMDS_NO-1)) { //TROUBLED LINE i<CMDS_NO does not work,  
                                  //if there is a next command
                close(new_fds[0]);
                dup2(new_fds[1],1);
                close(new_fds[1]);
            }
            execlp(array[i], array[i], param[i], NULL);

            } else {
                if (i!=0) { //if there is a previous command
                    close(old_fds[0]);
                    close(old_fds[1]);
                }

                if (i<CMDS_NO) { //if there is a next command
                    old_fds[0] = new_fds[0];
                    old_fds[1] = new_fds[1];
                }
            }
     }
     if (CMDS_NO>1) {
        close(old_fds[0]);
        close(old_fds[1]);
     }     

     while (1) { //wait for child processes to end
         wait(NULL);
         if(errno== ECHILD) {
             printf("all children ended\n"); 
             break;
         }
     }

return 0;
}

2 个答案:

答案 0 :(得分:1)

条件i<CMDS_NO始终为真,因为i从0到CMDS_NO-1。我想你的意思是把你的条件写成i<CMDS_NO-1。当然,i!=CMDS_NO-1同样有效。

请注意,这会影响您拥有if (i<CMDS_NO)的其他几个地方;这些也应该是if (i<CMDS_NO-1)

答案 1 :(得分:1)

这是正常的。

for (int i=0; i<CMDS_NO; i++) {

这意味着“只要i小于CMDS_NO”就会循环播放。一旦i == CMDS_NO循环停止;因此,在循环内,最高i将达到CMDS_NO - 1

PS:CMDS_NO是一个非常糟糕的变量名称,例如将其称为MAX_COMMANDS