一、基本概念
我们要知道管道为什么叫做管道,管道就好比我们生活中的水管,水总是从一端流向另一端,你总不能从水龙头往里灌水吧,它只能出水。管道也是类似的,数据从管子的一端传入,在另一端进行数据的读取。
什么是管道?当数据从一个进程流到另一个进程时,他们连接就是通过管道(pipe)来实现的,
这也就是它的工作模式是半双工通信。
二、匿名管道
基本的使用流程:
1)创建管道文件
int pipe(int pipefd[2]);
0索引代表读端,1索引代表写端
2)进行读/写管道文件
read(int pipefd[0]);
write(int pipefd[1]);
3)关闭管道文件
close(int pipefd[2]);
特点:
1)只能用于具有亲缘关系的进程之间进行通信。
2)不会在文件系统中体现出一个文件,只存在于内存中。
3)它是半双工的通信模式(具有固定的读端和写端,如果要互相传送数据,需要构建两个管道)
注意:管道文件创建不能在共享文件夹下
举例:父进程往管道文件写数据,子进程读取父进程写入管道文件的数据
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
int main()
{
int pipefd[2] = {0};
int ret = pipe(pipefd);
if(ret == -1)
{
perror("pipe failed");
return -1;
}
//创建子进程
pid_t pid = fork();
if(pid == 0)
{
//从管道读取数据
char buff[20] = {0};
read(pipefd[0],buff,20);
printf("从管道读取的数据是:%s\n",buff);
exit(0);
}else if(pid > 0)
{
//往管道写入数据
char buff[20] = "Hello,myson";
write(pipefd[1],buff,sizeof(buff));
}else
{
printf("create pid failed");
}
close(pipefd[0]);
close(pipefd[1]);
wait(NULL);
return 0;
}
三、有名管道
基本的使用流程:
1)创建管道文件
int mkfifo(const char *pathname, mode_t mode);
第一个是创建管道文件的路径及其名称
第二个是管道文件的权限
2)打开管道文件
int open(const char *pathname, int flags);
3)读/写管道文件
read(); / write();
4)关闭管道文件
close();
5)销毁管道文件
int unlink(const char *pathname);
特点:
1)可以在不同的进程中相互进行通信,不需要具有亲缘关系的进程,也可以在具有亲缘关系的进程中使用。
2)会在文件系统中体现出一个文件,即管道文件(注意:管道文件在Windows不存在,所以不能在共享文件夹中创建管道文件)。
3)管道文件仅仅是文件系统中的标示,并不在磁盘上占据空间。在使用时,在内存上开辟空间,作为两个进程数据交互的通道。
举例:两个不同进程进行管道通信,一个进程发送数据,另一个进程接收数据
发送的进程:
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int main()
{
int ret = mkfifo("./pipe",0644);
if(ret == -1)
{
perror("create pipe failed");
return -1;
}
int fd = open("./pipe",O_WRONLY);
if(fd == -1)
{
perror("open pipe failed");
return -1;
}
char buff[20] = "Hello,myfriend!";
write(fd,buff,sizeof(buff));
close(fd);
return 0;
}
接收的进程:
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int main()
{
int fd = open("./pipe",O_RDONLY);
if(fd == -1)
{
perror("open pipe failed");
return -1;
}
char buff[20] = {0};
read(fd,buff,sizeof(buff));
printf("收到的信息是:%s\n",buff);
close(fd);
unlink("./pipe");
return 0;
}
四、匿名管道和有名管道的区别
1)相同点:open打开管道文件以后,在内存中开辟了一块空间,管道的内容在内存中存放,读写数据都是在给内存的操作,并且都是半双工通讯。
2)不同点:有名在任意进程之间使用,无名在父子进程之间使用。