如何等待数据写入管道的另一端

我正在用C开发一个应用程序。父子进程通过管道进行通信。 在写入管道之前,父进程执行另一个语句。 在示例代码中,我使用sleep(10)来延迟。 在子进程中,它应该从管道中读取数据。 但是在子进程的管道读取端没有读取数据。

int main() { int pid; FILE *fp; fp = fopen("test.txt","w"); char *buff; int fd[2]; int count = 0 ; pipe(fd); pid = fork(); if(pid == 0) { close(fd[1]); ioctl(fd[0], FIONREAD, &count); fprintf(fp,"Value of count: %d ",count); buff = malloc(count); fprintf(fp,"\n TIME before read: %s",__TIME__); read(fd[0], buff, count); fprintf(fp,"\nbuffer: %s\n TIME after read %s", buff, __TIME__); } else{ close(fd[0]); sleep(10); //delay caused by application specific code replaced with sleep write(fd[1],"THIS is it",10); } fclose(fp); return 0; } 

如何使子进程等到数据写入另一端?

您的管道在阻止模式下打开,您无需更改它,这可能是您的意图。

但是,由于您要做的第一件事就是请求管道上等待的数据大小,然后盲目地跳转到读取那么多字节(在代码执行时很可能为零,因为父代还没有写任何东西)你不要阻止,而只是因为你没有要求而离开。

有很多方法可以做到这一点,包括选择循环。 如果您希望阻止读取直到数据可用,则在单个字节上执行此操作,然后填写剩余数据。

这绝不是如何正确执行此操作的示例,但它是一个简短的示例,说明如何等待单个字节,请求管道的读取大小以获取其余数据,读取它,以及继续这个,直到管道没有数据,父节点关闭它们的结束:

我希望你觉得这对你有帮助。

 #include  #include  #include  int main() { int pid = 0; // create pipe pair int fd[2]; pipe(fd); pid = fork(); if (pid == 0) { // child side char *buff = NULL; char byte = 0; int count = 0; // close write side. don't need it. close(fd[1]); // read at least one byte from the pipe. while (read(fd[0], &byte, 1) == 1) { if (ioctl(fd[0], FIONREAD, &count) != -1) { fprintf(stdout,"Child: count = %d\n",count); // allocate space for the byte we just read + the rest // of whatever is on the pipe. buff = malloc(count+1); buff[0] = byte; if (read(fd[0], buff+1, count) == count) fprintf(stdout,"Child: received \"%s\"\n", buff); free(buff); } else { // could not read in-size perror("Failed to read input size."); } } // close our side close(fd[0]); fprintf(stdout,"Child: Shutting down.\n"); } else { // close read size. don't need it. const char msg1[] = "Message From Parent"; const char msg2[] = "Another Message From Parent"; close(fd[0]); sleep(5); // simulate process wait fprintf(stdout, "Parent: sending \"%s\"\n", msg1); write(fd[1], msg1, sizeof(msg1)); sleep(5); // simulate process wait fprintf(stdout, "Parent: sending \"%s\"\n", msg2); write(fd[1], msg2, sizeof(msg2)); close(fd[1]); fprintf(stdout,"Parent: Shutting down.\n"); } return 0; } 

产量

 Parent: sending "Message From Parent" Child: count = 19 Child: received "Message From Parent" Parent: sending "Another Message From Parent" Parent: Shutting down. Child: count = 27 Child: received "Another Message From Parent" Child: Shutting down. 

我想以后

 ioctl(fd[0], FIONREAD, &count); the count is 0. read(fd[0], buff, count) will get no data. try read(fd[0], buff, 10) 

问题是获取写入管道的字节数。 你在fork()之后得到它。 如果首先执行读取过程,则它将不包含任何数据(并且计数将为零)。 如果写入进程首先执行,它将包含一些数据。

如何使子进程等到数据写入另一端?

由于您以阻塞模式打开管道,因此您应该尽可能多地读取数据,而不是尝试获取写入数据的大小。


这是您等待完整消息的修改示例:

 #include  #include  int main() { int pid; FILE *fp; fp = fopen("test.txt","w"); char *buff = malloc(1024); int fd[2]; int count = 0 ; pipe(fd); pid = fork(); if(pid == 0) { close(fd[1]); int i = 0; while ( i < 10 ) { fprintf(fp,"\n TIME before read: %s \n",__TIME__); read(fd[0], buff+i, 1); ++ i; } fprintf(fp,"Full message received!\nbuffer: %s\n TIME after read %s\n", buff, __TIME__); } else{ close(fd[0]); sleep(10); //delay caused by application specific code replaced with sleep write(fd[1],"THIS is it",10); } fclose(fp); return 0; }