linux – 使用EOF在未命名的管道上发送信号
我有一个测试程序,它使用用pipe()创建的未命名管道在
Linux系统上使用fork()创建的父进程和子进程之间进行通信.
通常,当发送进程关闭管道的写入fd时,接收进程从read()返回值0,表示EOF. 但是,似乎如果我在管道中填充了大量数据(在接收器开始读取之前可能是100K字节0),接收器在读取管道中的所有数据后就会阻塞 – 即使发送器已关闭它. 我已经验证发送过程已经用lsof关闭了管道,并且看起来非常清楚接收器被阻塞了. 这导致了一个问题:关闭管道的一端是一个可靠的方法让接收器知道没有更多的数据? 如果是,并且没有条件可以导致空的,关闭的FIFO上的read()阻塞,那么我的代码就会出错.如果不是,这意味着我需要找到一种发信号通知数据流结束的替代方法. 解析度 我很确定最初的假设是正确的,关闭管道导致阅读器侧的EOF,这个问题只是在黑暗中拍摄 – 想想可能有一些我忽略的微妙的管道行为.几乎你用管道看到的每个例子都是一个发送几个字节并退出的玩具.当您不再进行原子操作时,事情通常会有所不同. 无论如何,我试图简化我的代码以清除问题并成功找到我的问题.在伪代码中,我最终做了这样的事情: create pipe1 if ( !fork() ) { close pipe1 write fd do some stuff reading pipe1 until EOF } create pipe2 if ( !fork() ) { close pipe2 write fd do some stuff reading pipe2 until EOF } close pipe1 read fd close pipe2 read fd write data to pipe1 get completion response from child 1 close pipe1 write fd write data to pipe2 get completion response from child 2 close pipe2 write fd wait for children to exit 子进程读取管道1挂起,但只有当管道中的数据量变得很大时才会挂起.即使我关闭了child1正在阅读的管道,这种情况仍在发生. 查看源代码可以看出问题所在.当我分叉第二个子进程时,它抓取了自己的pipe1文件描述符副本,这些描述符保持打开状态.尽管只有一个进程应该写入管道,但在第二个进程中打开它会使其无法进入EOF状态. 这个问题没有出现在小型数据集中,因为child2正在迅速完成业务并退出.但是对于更大的数据集,child2没有快速返回,我最终陷入僵局. 解决方法
当写入器关闭写入结束时,read应返回EOF.
既然你做了一个管道,然后是一个fork,那么两个进程都会打开write fd.可能是在读者进程中你忘记关闭管道的写入部分. 警告:自从我在Unix上编程以来已经有很长一段时间了.所以它可能是不准确的. 以下是一些代码:http://www.cs.uml.edu/~fredm/courses/91.308/files/pipes.html.请查看下面的“关闭未使用”评论. #include <stdio.h> /* The index of the "read" end of the pipe */ #define READ 0 /* The index of the "write" end of the pipe */ #define WRITE 1 char *phrase = "Stuff this in your pipe and smoke it"; main () { int fd[2],bytesRead; char message [100]; /* Parent process message buffer */ pipe ( fd ); /*Create an unnamed pipe*/ if ( fork ( ) == 0 ) { /* Child Writer */ close (fd[READ]); /* Close unused end*/ write (fd[WRITE],phrase,strlen ( phrase) +1); /* include NULL*/ close (fd[WRITE]); /* Close used end*/ printf("Child: Wrote '%s' to pipe!n",phrase); } else { /* Parent Reader */ close (fd[WRITE]); /* Close unused end*/ bytesRead = read ( fd[READ],message,100); printf ( "Parent: Read %d bytes from pipe: %sn",bytesRead,message); close ( fd[READ]); /* Close used end */ } } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |