管道用于具有亲缘关系的进程之间的通信,又称匿名管道,以与命名管道区分。
通过管道的通信数据遵循“先进先出”原则,并且是单向通信,因此若有两个进程需要双向通信,则至少需要建立两个管道。
“具有亲缘关系的进程”是指父进程与子进程,或者父进程派生的2个子进程。
下面就直接上代码演示两个兄弟进程之间通过匿名管道传递数据:
#include <stdio.h>
int main()
{
int fdset[2];
int id;
if(-1 == pipe(fdset))
{
perror("pipe error\n");
return 0;
}
if(!fork())
{
id = getpid();
printf("I am child writer pid:%d parent:%d\n", id, getppid());
write(fdset[1], &id, sizeof(int));
}
else if(!fork())
{
read(fdset[0], &id, sizeof(int));
printf("I am child reader pid:%d parent:%d. My brother pid:%d\n",
getpid(), getppid(), id);
}
else
{
printf("I am parent pid:%d\n", getpid());
}
sleep(2);
close(fdset[0]);
close(fdset[1]);
printf("Bye from pid:%d\n", getpid());
return 0;
}
来看一下运行结果:
test@test:~$ gcc main.c
test@test:~$ ./a.out
I am parent pid:25192
I am child writer pid:25193 parent:25192
I am child reader pid:25194 parent:25192. My brother pid:25193
Bye from pid:25192
Bye from pid:25193
Bye from pid:25194
和代码对应起来一起看:
父进程进程号是25192,派生了2个进程,一个往pipe中写入自己的进程号,另外一个子进程从pipe中读出兄弟进程的进程号,并打印出来。
只有具有亲缘关系的进程才能通过fork共享文件打开表,而不同进程打开文件表最终指向的是同一个系统文件打开表,才实现了数据流的传递。