C - 同时从两个管道(来自两个子进程的父进程)读取?
Posted
技术标签:
【中文标题】C - 同时从两个管道(来自两个子进程的父进程)读取?【英文标题】:C - Reading from two pipes(parent from two child processes) simultaneously? 【发布时间】:2012-10-01 22:37:02 【问题描述】:我有一个父进程,其中有两个子进程从中分叉。我创建了两个管道(每个孩子一个)。对于每个管道,我已经关闭了父级的写入端和子级的读取端。
我遇到的问题是让父级同时从每个子管道中读取。它似乎只是从我尝试读取的第一个管道中读取。
//PARENT
while(1)
read(fd[0], buffer, sizeof(buffer));
//print out buffer
read(fd2[0], buffer2, sizeof(buffer2));
//print out buffer2
唯一打印的是我第一次阅读电话的信息。我得出的结论是 read 似乎阻止了其他读取。我在网上查看并在 select 中找到了一个可能的解决方案,但无法弄清楚如何使用管道实现它(似乎在任何地方都没有任何示例)。
有人能解释一下 select 如何与管道一起工作,或者告诉我任何其他可能解决我的问题的方法吗?
【问题讨论】:
阅读您的系统文档以供选择。 (man select
)。许多精选的手册页都有相当丰富的示例。
您的大纲代码将同步读取来自一个孩子的消息,然后是另一个孩子。我相信buffer2
的大小与buffer
的大小相同,因为您也使用buffer
的大小进行第二次读取。
【参考方案1】:
您的阅读被阻止。这意味着当您调用 read 时,它会一直等待,直到它具有您请求的字节数或流关闭(命中 EOF)。
您需要使管道非阻塞(使用fcntl(fd[0], F_SETFL, O_NONBLOCK);
)或使用线程。
编辑添加 Jonathan Leffler 的观点:
如果您确实使用非阻塞,调用select() 将是最有效的。这将节省您浪费大量 CPU 时间(启用非阻塞时会发生这种情况,因为当没有数据存在时读取会立即返回)。例如:
int fds[2];
...
fds[0] = fd[0];
fds[1] = fd2[0];
while...
select(2, &fds, NULL, NULL, NULL);
read(...);
read(...);
【讨论】:
设置 O_NONBLOCK 可能会导致轮询繁忙;使用select()
或其变体之一可能会更好。以上是关于C - 同时从两个管道(来自两个子进程的父进程)读取?的主要内容,如果未能解决你的问题,请参考以下文章