一、无 名管道
管道,通常指无名管道,是UNIX系统IPC最古老的形式
特点:
- 半双工(即数据只能在一个方向上流动),具有固定的读端和写端。
- 它只能用于具有亲缘关系的进程之间的通信(也是父子进程或者兄弟进程之间)。
- 它可以看成是一种特殊的文件,对于它的读写也可以使用普通的read、write 等函数。但是它不是普通的文件,并不属于其他任何文件系统,并且只存在于内存中。
要点:
1、#include // 头文件
2、int fd[2]; // fd[0]:读端 / fd[1]:写端
3、 pipe(fd) //创建管道
4、传输信息时,发送端先关闭读端fd[0],再进行写操作
接收端反之,close(fd[1]); read( );
demo:无名管道,父进程–>子进程
#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
int main()
{
int fd[2]; //fd[0]:读端 fd[1]:写端
pid_t pid; //typedef定义类型,short
char buf[128];
if(pipe(fd) == -1) //创建管道,创建成功返回0,失败返回-1
{
printf("creat pipe failed\n");
}
pid = fork();//创建进程
if(pid<0)
{
printf("creat child failed\n");
}
else if(pid >0) //父进程
{
printf("this is father\n");
close(fd[0]); //关读端
write(fd[1],"hello word from father",30); //写消息
wait(); //等待子进程退出
}
else
{
printf("this is child\n");
close(fd[1]); //关写端
read(fd[0],buf,128); //读消息
printf("read from father:%s\n",buf);
exit(0);
}
return 0;
}
二、FIFO(命名管道)
特点
- FIFO可以在无关的进程之间交换数据,与无名管道不同。
- FIFO有路径名与之相关联,它以一种特殊设备文件形式存在于文件系统中。
FIFO创建
创建命名管道时,可能会存在管道名已存在造成创建失败退出现象
1、mkfifo() 创建命名管道
2、perror()函数 显示错误原因到标准输出
//int mkfifo(const char *pathname,mode_t mode)
//mode与open函数中的mode相同
int main()
{
if(mkfifo("./guandao",0600) == -1 && errno != EEXIST)
{
printf("mkfifo failer\n");
perror("why");
}
return 0;
}
FIFO通信传输
当open一个FIFO时,是否设置非阻塞标(O_NONBLOCK)有区别:
1、若没有指定,只读open(O_RDONLY)要阻塞到某个其他的进程为写(write)而打开此FIFO。反之只写打开(O_WRONLY),要等到另一个文件只读打开。
(eg:——-将一个只写打开,等待另一个write运行时,实现信息传输)
2、若指定O_NONBLOCK,则只读open立即返回,而只写open将出错返回-1
<<FIFO的通信方式类似于在进程中使用文件来传输数据,只不过FIFO类型文件同时具有管道的特性。在数据读出时,FIFO管道中同时清除数据,并且“先进先出”。>>
demo: FIFO 阻塞通信
fifo_read.c
#include<stdio.h>
#include<stdlib.h>
#include<sys/stat.h>
#include<sys/types.h>
#include<errno.h> //perror
#include<fcntl.h>
int main()
{
if(mkfifo("./guandao",0600) == -1 && errno != EEXIST)
{
printf("mkfifo failer\n");
perror("why");
}
int fd = open("./guandao",O_RDONLY);//以只读打开
printf("open success\n");
return 0;
}
fifo_write.c
int main()
{
int fd = open("./guandao",O_WRONLY); //以只写打开
printf("write success\n");
return 0;
}
在两个终端里用 gcc 分别编译运行上面两个文件,只运行其中一个会阻塞等待,当另一个运行时,两个进程才会打印出相应内容。
如果通过FIFO,两个进程传递信息,通过分别 read(fd,buf,size)及write(fd,buf,size)进行<参考收藏博文demo代码>