进程间通信----管道
进程间通信
了解管道之前,我们先要了解什么是进程间通信,为什么要进程间通信,进程间通信有什么好处,以及有哪些进程间通信方式!
背景:
1.在很多情况下,一些大型的程序使用的是多个进程相互配合完成任务
2.但是 进程具有独立性 ,无法方便的进行进程之间的沟通
3.为了使多个进程能容易的进行进程间的交流,引出进程间通信
作用:
1.数据交换
2.资源共享
3.相互通知
4.进程控制:某些进程需要被另一个进程完全控制
分类:
最 古老 的方式:
管道(pipe):匿名管道、命名管道
System V IPC标准:消息队列、共享内存、信号量
POSIX PIC标准:消息队列、共享内存、信号量、互斥量、条件变量、读写锁
管道
匿名管道:
1.实质:操作系统内核中的一块内存
2.操作方法:本着Linux中一切皆文件的原则,于是乎采用文件I\O的方式操作管道
父子进程实现单向通信代码:
#include<stdio.h>
#include<unistd.h>
#include<string.h>
#include<errno.h>
int main(){
int fd[2];
if(pipe(fd) < 0){
perror("pipe error");
return -1;
}
pid_t pid = fork();
if(pid < 0){
perror("fork error");
return -1;
}
if(pid == 0){
//child close write
close(fd[1]);
char buf[1024] = {0};
read(fd[0], buf, sizeof(buf) -1);
printf("buf = %s\n",buf);
close(fd[0]);
}
else{
//father close read
sleep(2);
close(fd[0]);
char msg[] = "xixixhahahzhoudaxinbalalala";
write(fd[1], msg, strlen(msg));
close(fd[1]);
}
return 0;
}
3.创建管道:
int pipe(int fd[2]);
返回值:成功0,失败错误码
参数: fd[2] 文件描述符数组
fd[0] 表示读(从管道中读取内容)
fd[1] 表示写(将内容写入管道当中)
通过操作该文件描述符数组操作管道(也就是管道所对应的内存)
失败原因:
管道资源(内存资源)不足
文件描述符达到上限
求一个进程可以申请的最大管道数代码:
#include<stdio.h>
#include<unistd.h>
#include<string.h>
#include<sysexits.h>
int main(){
int count = 0;
while(1){
usleep(40000);
int fd[2] = {0};
int ret = pipe(fd);
if(ret < 0){
printf("i can pipe %d times\n", count);
perror("pipe!!");
break;
}
else{
printf("this is %d pipe\n",count);
}
count++;
}
return 0;
}
结果展示:
4.管道读写规则:
a.管道为空:read调用阻塞
b.管道已满:write调用阻塞
c.写端关闭:read返回0
d.读端关闭:write错误退出(产生SIGPIPE信号)
c.写入数据小于管道内存大小:写入操作保证具有原子性,反之则不保证具有原子性
注:原子性表示该操作不会被打断,直接完成。
命名管道:
1.实质:本体仍是内核中的一块内存
一种特殊类型的文件(文件系统可见)(该文件是管道入口)
2.操作方法:通过文件I\O操作管道
3.创建管道文件:
a.命令行创建
mkfifo filename 创建管道入口文件
b.代码创建
int mkfifo(const char filename, mode_t mode);
filename: 文件名称
mode: 文件权限
4.打开规则:
用open打开
读、写需要 同时打开,否则会阻塞
通过采用只读方式打开:得到读取管道内容的文件描述符
通过采用只写方式打开:得到将数据写入管道的文件描述符
匿名管道和命名管道的区别:
匿名管道只能用于具有亲属关系的管道之间,命名管道用于任意管道之间
匿名管道打开方式是pipe函数,命名管道打开方式是open
管道总结:
a. 匿名管道 只能用于具有亲属关系的进程之间通信 命名管道 用于任意进程之间
b.管道传输面向字节流,收发数据灵活,数据无规则发送,数据无边界
c.管道生命周期随进程,进程结束,管道释放
d.内核对管道操作进行同步和互斥
e.管道是半双工单向通信,数据只有一个流向
f.本质上都是操作系统内核中的一段内存
关于管道的内容到此结束,谢谢大家的支持!!