管道是UNIX系统IPC最古老的形式,并且所有UNIX系统都提供此种通信机制。管道有下面两种局限性。
1.历史上,它们是半双工的,数据只能在一个方向上流动
2只能在公共祖先的进程之间使用。例如,父子进程之间就可应用管道。
尽管有这两种局限性,半双工管道仍是最常用的IPC形式
管道是用pipe函数创建的
#include <unistd.h>
int pipe(int pipefd[2]);
返回值:若成功则返回0,若出错则返回-1
pipefd[0]为读而打开, pipefd[1]为写而打开
fstat函数对管道的每一端都返回一个FIFO类型的文件描述符,可以用S_ISFIFO宏来测试管道。详情见http://blog.csdn.net/aspnet_lyc/article/details/20716169
单个进程中管道几乎没有任何用处。通常,调用pipe的进程接着调用fork,这样就创建了从父进程到子进程的IPC管道。
#include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <string.h> main() { int fd[2]; int pid; char buf[1024]; int r; if (pipe(fd) < 0) printf("pipe error\n"), exit(-1); if ((pid = fork()) < 0) printf("fork error\n"), exit(-1); if (pid > 0) { close(fd[0]); write(fd[1], "Hello World\n", 12); } else { close(fd[1]); r = read(fd[0], buf, 1024); write(STDOUT_FILENO, buf, r); } exit(0); }
Hello World
当管道的一端被关闭后,下列两条规则起作用:
1.读一个写端已被关闭的管道时,在所有数据都被读取后,read返回0,以指示达到了文件结束处。
如下程序将会阻塞,“子进程终止”并不会被打印出来,执行结果输出 Hello World
#include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <string.h> main() { int fd[2]; int pid; char buf[5]; int r; if (pipe(fd) < 0) printf("pipe error\n"), exit(-1); if ((pid = fork()) < 0) printf("fork error\n"), exit(-1); if (pid == 0) { //子进程 close(fd[1]); //子进程关闭写 while(1) { r = read(fd[0], buf, 5); if (r > 0) { buf[r] = 0; printf("%s", buf); } else if (r == 0) break; else printf("此行不会被打印,因为读到结尾处read函数阻塞\n"); } exit(0); } else { //父进程 close(fd[0]); //父进程关闭读 write(fd[1], "Hello World\n", 12); wait(0); printf("子进程终止\n"); exit(0); } }
执行结果
Hello World
子进程终止
#include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <string.h> main() { int fd[2]; int pid; char buf[5]; int r; if (pipe(fd) < 0) printf("pipe error\n"), exit(-1); if ((pid = fork()) < 0) printf("fork error\n"), exit(-1); if (pid == 0) { close(fd[1]); //子进程关闭写 while(1) { r = read(fd[0], buf, 5); if (r > 0) { buf[r] = 0; printf("%s", buf); } else if (r == 0) break; else printf("此行不会被打印,因为读到结尾处read函数阻塞\n"); } exit(0); } else { close(fd[0]); write(fd[1], "Hello World\n", 12); close(fd[1]); //父进程关闭写 wait(0); printf("子进程终止\n"); exit(0); } }
#include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <string.h> main() { int fd[2]; int pid; char buf[5]; int r; if (pipe(fd) < 0) printf("pipe error\n"), exit(-1); if ((pid = fork()) < 0) printf("fork error\n"), exit(-1); if (pid == 0) { //子进程 close(fd[0]); //子进程关闭读 while(1) { r = write(fd[1], "Hello World\n", 12); if (r == -1) break; } exit(0); } else { //父进程 close(fd[0]); //父进程关闭读 wait(0); printf("子进程终止\n"); exit(0); } }
原文:http://blog.csdn.net/aspnet_lyc/article/details/20773121