管道是最初的IPC方式,经常会在shell命令中使用。
引用《UNIX网络编程》上例子:
我们在某个Unix shell中输入下面的命令:
who | sort | lp
这个shell包含三个命令,who命令的输出(通过管道)做为sort命令的输入,sort的输出做为lp命令的输入,最终显示lp命令的输出。
这里暂不关心每个命令的作用,只考虑管道是如何传递的。
shell会创建三个进程分别执行这三个命令,三个进程间通过管道进行数据传输。如下图所示:
接下来通过程序进行模拟,为方便起见,我们只考虑两个命令通过管道通信。
比如执行shell命令:命令1 | 命令2
命令1、命令2会由shell的两个子进程分别执行,两命令对应的两个进程不妨叫做大儿子、小儿子。
大儿子会对其弟弟问好,小儿子接收其哥哥的信息并打印到标准输出。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
/*主进程fork两个子进程,两子进程通过管道传递数据*/
int main()
{
int fields[2];
char buf[100];
int pid1, pid2;
// 创建一个管道
if(pipe(fields) < 0 )
{
perror("创建管道失败!");
}
// 父进程创建第一个儿子
if((pid1 = fork()) < 0)
{
perror("创建子进程失败");
}
if(0 == pid1) // 大儿子
{
printf("大儿子有话对兄弟说: Hi,how are you?\r\n");
char words[] = "Hi,how are you?";
write(fields[1], words, sizeof(words));
}
if(pid1 > 0 ) // 父进程
{
// 父进程创建第二个儿子
if((pid2 = fork()) < 0)
{
perror("创建子进程失败");
}
if(0 == pid2) // 小儿子
{
printf("小儿子接收哥哥的信息:");
read(fields[0], buf, sizeof(buf));
printf("%s\r\n", buf);
}
if(pid2 > 0)
{
waitpid(pid1, NULL, 0);
waitpid(pid2, NULL, 0);
}
}
return 0;
}
编译并执行:
$ gcc pipe.c
$ ./a.out
大儿子有话对兄弟说: Hi,how are you?
小儿子接收哥哥的信息:Hi,how are you?
2011-11-11 任洪彩 qdurenhongcai@163.com
转载请注明出处。