管道是一种文件,
无名管道:
1)没有名字的文件,没有在磁盘里面形成具体的文件
2)不能用lseek定位
3)退出程序后,程序内部的管道资源会被释放,下次运行需要在创建,才能使用
4)只能用在亲缘进程(父子,爷孙,兄弟)
5)pipe实在fork之前创建的(4个读写端口,两个读两个写,才能够实现亲缘进程双向通信)
6)无名管道是在内核空间创建出来的。
7)半双工通信(读端只能读,不能写)
8)无名管道不能用open打开
9)写操作没有原子性。(不能给他一个多进程的环境,只能进程单一的通信)
原子性(多线程操作,全局共享区:数据):一旦任务(代码—任务函数)启动,一定要做完才能做其他事情(不能打断他,不能影响他)
无名管道的API
创建一条无名管道并且给你两个文件描述符(读写的文件描述符)
pipefd[0]:读端
pipefd[1]:写端
1)创建管道
2)创建进程
3)关闭管道
示例代码:
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <unistd.h>
int main()
{
int pipefd[2] = {0};
pipe(pipefd); //创建无名管道
pid_t ret = fork(); //创建进程
if (ret == -1)
{
perror("fork");
}
else if (ret == 0)
{
char msg_data[32] = {0};
memset(msg_data, 0, 32);
printf("请输入发给父亲的信息:");
scanf("%s", msg_data);
write(pipefd[1], msg_data, strlen(msg_data));
exit(0);
}
else
{
char msg_data[32];
memset(msg_data, 0, 32);
read(pipefd[0], msg_data, 32);
printf("儿子说:%s\n", msg_data);
wait(NULL);
}
//关闭管道文件
close(pipefd[0]);
close(pipefd[1]);
return 0;
有名管道:
有名字的管道,所有具体的文件,存放在闪存里面。
特点:
1)血缘与非血缘都可以用
2)可用open打开(才有文件描述符)
3)不能用lseek定位
4)写操作具有原子性。
5)全双工(一个管道只有一个文件描述符:读和写)
6)退出程序后,有名管道可以一直使用,直到你把管道文件删掉。 (rx xxx)
有名管道的API
代码思路:
1)第一步:
判断管道文件存不存在 — access();
access:可以判断文件是否存在,可读,可写,可执行 #include <unistd.h> /tmp/dante_fifo F_OK int access(const char *pathname, int mode); pathname:文件的路径 mode:功能选项 R_OK W_OK X_OK F_OK: 文件存不存在
存在:进入第三步
不存在则进入第二步
2)第二步:
创建管道文件,进入第三步
3)第三步:
直接打开
4)第四步:
调用
read
write
发送和接收信息
5)第五步:
close 关闭管道
示例代码:
小明发送信息给小红
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>
#define PATH "/tmp/fifo"
int main()
{
if(access(PATH, F_OK))
{
umask(0000);
//创建管道文件
mkfifo(PATH, 0777);
}
//打开管道文件
int fd = open(PATH, O_RDWR);
if(fd == -1)
{
perror("open failed");
exit(-1);
}
char msg_data[10];
while(1)
{
memset(msg_data,0,10);
printf("发给小红的信息:");
scanf("%s", msg_data);
write(fd, msg_data, strlen(msg_data));
}
close(fd);
return 0;
}
小红接收到小明信息
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>
#define PATH "/tmp/fifo"
int main()
{
if(access(PATH, F_OK))
{
umask(0000);
//创建管道文件
mkfifo(PATH, 0777);
}
//打开管道文件
int fd = open(PATH, O_RDWR);
if(fd == -1)
{
perror("open failed");
exit(-1);
}
char msg_data[10];
while(1)
{
memset(msg_data,0,10);
printf("小红接收到小明的信息:");
read(fd, msg_data, 10);
printf("%s\n", msg_data);
}
close(fd);
return 0;
}
代码实现效果: