2009-12-24 31 views
1

我正在写一个实现管道的小程序,就像他们在shell中工作一样。 即:fork()和pipe()的小问题

ls -hal | sort | grep p | wc 

它做工精细,用个小问题,在一行上,当CMD_NO = N,I biggerthan CMD_NO比较没有工作,但我=(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; 
} 
+0

多想想你要的时候'i'是'0','CMDS_NO-1',和值之间发生什么。请注意,无论何时你在循环中都会有'i dave4420 2009-12-24 15:19:04

回答

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

这很正常。

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

这意味着 “循环只要i小于CMDS_NO”。只要i == CMDS_NO循环将停止;所以,在循环内部,最高的i将达到CMDS_NO - 1

PS:CMDS_NO是一个非常可怜的变量名,叫它MAX_COMMANDS例如