我试图解决这个练习: “制作一个程序,作为参数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循环中。为什么?
答案 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;
}