管道是UNIX系统最古老的的进程间通信方式(基本不再使用),历史上的管道通常是半双工(只允许单项数据流动),现在的系统大都可以全双工(数据可以双向流动)
管道可分为无名管道和有名管道两种;接下来将用代码的形式介绍两种管道实现进程间的通信。
一、 有名管道
命令:mkfifo
函数:
#include <sys/types.h>
#include <sys/stat.h>
Int mkfifo(const char *pathname, mode_t mode);
功能:创建管道文件
pathname:文件路径
mode:权限
返回值:成功返回0,失败返回-1
***编程模型***
进程A 进程B
创建管道(mkfifo) ...
打开管道(open) 打开管道
读/写管道(read/write) 读/写数据
关闭管道(close) 关闭管道
删除管道(unlink) ...
有名管道进程A的实现代码:
#include<stdio.h>
#include<string.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
int main()
{
//1.打开管道文件
int fd = open("/tmp/fifo",O_RDONLY);
if(0 > fd)
{
perror("open");
return -1;
}
//2.读数据
while(1)
{
char buf[1024] = {};
read(fd,buf,sizeof(buf));
if(0 == strcmp(buf,"quit"))
{
printf("退出\n");
break;
}
printf("read:%s\n",buf);
}
//关闭管道文件
close(fd);
return 0;
}
有名管道进程B的实现代码
#include<stdio.h>
#include<string.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
int main()
{
//1.创建管道文件,一般保存在/tmp目录下
if(mkfifo("/tmp/fifo",0644))
{
perror("mkfifo");
return -1;
}
//2.打开管道
int fd = open("/tmp/fifo",O_WRONLY);
if(0 > fd)
{
perror("open");
return -1;
}
//3.写数据
char buf[1024] = {};
while(1)
{
printf(">");
gets(buf);
write(fd,buf,strlen(buf)+1);
if(0 == strcmp(buf,"quit"))
{
printf("通信完成\n");
break;
}
}
//关闭管道文件
close(fd);
return 0;
}
二、无名管道
无名管道(用于通过fork创建的父子进程之间通信)
#include <unistd.h>
int pipe(int pipefd[2]);
功能:创建无名管道
pipefd:用来存储内核返回的文件描述
pipefd[0] 用于读操作
pipefd[1] 用于写操作
无名管道的实现代码
#include<stdio.h>
#include<string.h>
#include<unistd.h>
int main()
{
//创建管道
int pipefd[2] = {};
//打开无名官道
if(pipe(pipefd))
{
perror("pipe");
return -1;
}
//创建进程,父进程写关闭读
if(fork())
{
close(pipefd[0]);
printf("父进程:%u\n",getpid());
while(1)
{
char buf[1024] = {};
usleep(1000);
printf(">");
gets(buf);
write(pipefd[1],buf,strlen(buf)+1);
if(0 == strcmp(buf,"quit"))
{
printf("通信结束\n");
close(pipefd[1]);
return 0;
}
}
}
else//子进程读,关闭写
{
close(pipefd[1]);
printf("子进程:%u\n",getpid());
while(1)
{
char buf[1024] = {};
read(pipefd[0],buf,sizeof(buf));
if(0 == strcmp(buf,"quit"))
{
printf("通信结束\n");
close(pipefd[0]);
return 0;
}
printf("read:%s\n",buf);
}
}
return 0;
}