这是一个example来说明我的意思:
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
int main(void)
{
int fd[2], nbytes;
pid_t childpid;
char string[] = "Hello, world!\n";
char readbuffer[80];
pipe(fd);
if((childpid = fork()) == -1)
{
perror("fork");
exit(1);
}
if(childpid == 0)
{
/* Child process closes up input side of pipe */
close(fd[0]);
/* Send "string" through the output side of pipe */
write(fd[1], string, (strlen(string)+1));
exit(0);
}
else
{
/* Parent process closes up output side of pipe */
close(fd[1]);
/* Read in a string from the pipe */
nbytes = read(fd[0], readbuffer, sizeof(readbuffer));
printf("Received string: %s", readbuffer);
}
return(0);
}
但是,如果我的一个进程需要连续写入管道而另一个管道需要读取呢?
上面的示例似乎只适用于一次写入和一次读取。
答案 0 :(得分:24)
您的管道是单向流 - 每端都有一个文件描述符。没有必要关闭()管道的任何一端以允许数据沿其传递。
如果您的管道跨越进程(即在fork()之前创建,然后父级和子级使用它进行通信)您可以有一个写入和一个读取结束。然后,最好关闭管道的不需要的末端。这将
如果您的管道跨越线程(在同一过程中),则不要关闭管道的不需要的末端。这是因为文件描述符由进程保存,并且为一个线程关闭它将为所有线程关闭它,因此管道将变得不可用。
没有什么可以阻止你让一个进程连续写入管道而另一个进程读取。如果这是一个问题,那么您可以提供更多详细信息来帮助您。
答案 1 :(得分:11)
执行fork后,所有fds都重复。每个过程都打开管道的两端。如果您只想使用一端,则应关闭另一端(如果您的进程写入,请关闭读取端)。
除了明显的事实,如果你不关闭描述符,操作系统将在打开的文件表中保留额外的条目,如果你不关闭管道的写端,读者将永远不会收到EOF,因为仍有将数据输入管道的方法。 AFAIK(和IIRC)没有关闭其他进程中的读取fd没有问题 - 也就是说,除了文件无缘无故地打开之外。
在退出应用程序之前关闭所有描述符(也就是说,在每个进程中完成读/写操作后关闭管道的另一端)也建议(这是好的做法,而不是它影响太大) )
答案 2 :(得分:0)
管道不会给你双向通道,它也不会是多播。一个管道只有两端,它没有一个写端和多个读端。
如果你想要很多读者,那么你需要尽可能多的管道来读取你的读者。
答案 3 :(得分:0)
“上面的示例似乎仅适用于一次写入和一次读取。”
这是因为在读取和写入代码后退出。您需要继续写入循环并循环读取以实现连续性。它似乎与FD关闭没有任何关系。正如之前的回复中所提到的,每个进程都需要一端,所以另一端关闭。
我希望我理解正确的查询。
答案 4 :(得分:0)
仅用于同步,以确保操作的原子性