进程间通信的七种方式
(1)无名管道顾名思义以一个没有名字的管道,是一个特殊的文件,存在于内存上,不在文件系统展示;
(2)无名管道会返回两个文件描述符,分别对应管道的读端和写端,当两端都被关闭,管道文件从内存上消失;
(3)管道文件没有真实文件,所以不用open操作,使用特殊api打开(pipe)
(4)管道文件适用于亲缘进程间通信
(1)顾名思义,有名管道是有名字 的,会在文件系统创建一个管道文件,管道 文件类型为p
(2)管道文件只用于进程间通信,不用于存储数据,且消息是一次性的
(3)对于有名管道可以采取open函数打开,但是创建有名管道需要mkfifo函数
注:管道特点
当管道读端存在,写端有多少数据写多少数据,知道写满64k,在write处阻塞
当管道读端不存在,写管道,会造成管道破裂,内核会向用户空间发送一个SIGPIPE信号,导致进程结束
当管道写端存在,读管道,有多少数据读多少数据,没有数据时,在read处阻塞
当管道写端不存在,读管道,有多少数据读多少数据,没有数据时,read不会阻塞
管道文件本质上实现的事半双工通信,使用两个管道文件可以实现全双工
(1)信号是模拟底层硬件的中断操作,中断就是打断当前正在做的事,去做另一件事
(2)信号是软件实现的,中断是硬件实现的
(3)信号 是linux内核实现的,没有linux,就没有信号的概念
(4)用户可以给某个进程发送信号,进程也可以给某个进程发送信号(kill,raise),内核也可以给某个进程发送信号(SIGPIPE,SIGCHLD)
(5)进程收到信号后有三种操作,默认,捕获,忽略
相关api
sighandler_t signal(int signum, sighandler_t handler);
//定义信号处理函数
void handler(int signo)
{
//判断传过来的是哪个信号
if(signo == SIGINT)
{
printf("用户按下了ctrl + c键,被我捕获了\n");
}
}
注:信号不能传递数据
以上三个是linux内核提供的通信方式
以下三个是system V提供的
消息队列本质上在内核空间维护了一个队列,多个进程使用ftok函数获得一个相同的key,通过key值使用msgget函数创建消息队列,消息分为数据域和类型域,相同类型的消息满足先进先出的原则,多个进程都可以向消息队列写入和读取消息(msgsnd,msgrcv),消息队列也是一次性的,
程序关闭后,消息队列不会消失
共享内存的操作不是一次性的,当共享内存段中的数据被读取后,依然存在
共享内存是所有进程间通信方式中效率最高的,原因是,操作共享内存段时,无需进行用户空间和内核空间的切换
共享村村的原理是将同一块物理地址空间通过内核中的共享内存,分别映射到不同的进程中。
信号灯集是进程间同步互斥机制
信号灯集是信号量的集合,信号灯集中可以存放一个或多个信号灯;
信号灯集中的每一个灯都控制一个进程,信号灯集中灯的编号从0开始
每一个灯都是一个value值,当value值为0,等待该资源的进程,处于阻塞状态
Socket通信是一种在Linux操作系统中实现进程间,可以是跨主机的通信机制。