管道是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