分叉后

时间:2016-06-17 14:50:50

标签: c pipe fork

我试图解决这个练习: “制作一个程序,作为参数2接收其他程序(例如:”flow ls wc“)。它应该运行两个程序,使用第一个程序的输出作为第二个程序的输入并测量发送的数据量。在你的标准输出上每秒都有数量。“

我有这个:

int fluxo = 0;

void fa(){
    printf("\nFlux: %d\n", fluxo);
    fluxo = 0;
    alarm(1);
}


int main(int argc,char **argv){
    int pd[2];
    pid_t p;
    pipe(pd);
    char *buf;
    signal(SIGALRM,fa);
    alarm(1);

    if( (p=fork())==0 ){    
        close(pd[0]);
        dup2(pd[1],1);
        close(pd[1]);
        execlp(argv[1],argv[1],NULL);
        exit(EXIT_FAILURE);
    }
    else{
        wait(NULL);
        while(read(pd[0],&buf,1)==1)
            fluxo++;
        close(pd[1]);
        dup2(pd[0],0);
        close(pd[0]);
        execlp(argv[2],argv[2],NULL);
        exit(EXIT_FAILURE);
    }
    exit(EXIT_SUCCESS);
}

我正在使用while循环来测量数据量。然而,即使在子进程中的execlp发送了它的数据之后,我仍然陷入困境,因此它没有执行第二个程序..即使在读取管道中的所有数据之后它仍然停留在while循环中。为什么?

1 个答案:

答案 0 :(得分:1)

首先,您声明char* buf,但您的指针未分配。我认为您打算使用char buf(因为您在阅读中使用了&buf)。

你的while循环没有停留,对read的调用是。实际上,当您调用pd[1]函数时,您的父进程仍然打开了read描述符。因此,当您的缓冲区为空时,它将等待。

你应该替换它:

else{
        wait(NULL);
        while(read(pd[0],&buf,1)==1)
            fluxo++;
        close(pd[1]);
        dup2(pd[0],0);
        close(pd[0]);
        execlp(argv[2],argv[2],NULL);
        exit(EXIT_FAILURE);
    }

由此:

else{
        close(pd[1]);
        wait(NULL);
        while(read(pd[0],&buf,1)==1)
            fluxo++;
        dup2(pd[0],0);
        close(pd[0]);
        execlp(argv[2],argv[2],NULL);
        exit(EXIT_FAILURE);
    }

修改: 注意: 每字节读取字节效率不高,使用更大的缓冲区可以获得更好的性能。例如: char buf[1024]

和你的循环:

for(;;){
    ssize_t rd = read(pd[0], buf, 1024);
    if(rd==-1){
     perror("Reading");
     exit(EXIT_FAILURE);
    }
    if(rd==0) break;
    fluxo+=rd;
}