局限性
(1)半双工,只能数据在一个方向上流动,某些系统提供全双工,为了可移植性,决不预先假定系统支持全双工、
(2)只能在具有公共祖先的两个进程间使用
#include <unistd.h>
int pipe(int fd[2]);
//返回值 成功返回0,出错返回-1
经由参数fd返回两个文件描述符,fd[0]为读打开,fd[1]为写打开。fd[1]的输出是fd[0]的输入。
规则
(1)当read一个 写端已被关闭的管道时,所有数据读取后,read返回0表示文件结束。
(2)如果write一个 读端已被关闭的管道时,则产生信号SIGPIPE。如果忽略该信号或者捕捉该信号并从其处理程序返回,则write返回-1,errno设置为EPIPE。
实例
通常创建一个管道后,fork()一个子进程,父子进程一个关闭读,一个关闭写,分别进行读写操作。
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main()
{
int fd[2];
pid_t pid;
int n;
char buf[100];
if(pipe(fd) < 0)
{
perror("pipe()"),exit(1);
}
pid = fork();
if(pid < 0)
{
perror("fork()"),exit(1);
}
else if(pid > 0)
{
close(fd[0]);
sleep(1);
write(fd[1], "laijiashuai\n", 12);
}
else
{
close(fd[1]);
n = read(fd[0], buf, sizeof(buf));
write(STDOUT_FILENO, buf, n); //打印到屏幕
}
exit(0);
}
命名管道
不用fork()出子进程,在两个进程间通信。
读端:
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
int main()
{
int n;
char buf[100];
if(mkfifo("./namepipe",0666|S_IFIFO) == -1) //创建命名管道
perror("mkfifo"),exit(1);
int fd = open("./namepipe", O_RDONLY);
if(fd < 0)
perror("open"),exit(1);
n = read(fd, buf, sizeof(buf)); //如果没有写入则一直等待
write(STDOUT_FILENO, buf, n);
return 0;
}
写端:
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
int main()
{
int n;
char buf[100];
int fd = open("./namepipe", O_WRONLY);
if(fd < 0)
perror("open"),exit(1);
write(fd, "laijiashuai\n", 12);
return 0;
}