进程通信的本质就是不同进程能访问同一个内存区
IPC命名空间
- 在 Linux 中,IPC(Inter-Process Communication)命名空间用于隔离进程间通信的资源,包括共享内存、信号量和消息队列。IPC 命名空间是 Linux命名空间的一种类型,它允许在同一主机上创建多个隔离的 IPC 实例,每个实例都有自己的 IPC 资源。
- 通过 IPC 命名空间的隔离,不同的进程可以在各自的命名空间中创建和使用 IPC资源,而不会相互干扰。这对于容器化应用和虚拟化环境非常有用,因为它们可以在同一主机上运行多个隔离的进程,并且每个进程可以拥有自己的 IPC资源。
- 如果两个进程的IPC命名空间相同,那么这两个进程可以访问这个命名空间的内存空间。
无名管道
无名管道:适用于亲缘进程间的通信,半双工模式,单向传输,字节传输。
为什么没有亲缘关系的进程不能用无名管道?
无法找到写file和读file
命名管道
命令管道允许不相关进程读写相同文件,依赖于名称进行识别和引用,而不仅仅看文件描述符。
命名管道也是半双工的,所以需要多个命名管道实现全双工。
int fifo_read(){
int ret=mkfifo("./temp/test",0644);
if(ret==-1&&errno!=EEIXST){
perror("mkfifo failed");
return -1;
}
int fd=open("./temp/test",O_RDONLY);
if(fd==-1){
perror("fail");
return -1;
}
while(1){
char buf[1024]={0};
read(fd,buf,1024);
printf(buf);
}
}
int fifo_write(const char *buf){
int ret=mkfifo("./temp/test",0644);
if(ret==-1&&errno!=EEIXST){
perror("mkfifo failed");
return -1;
}
int fd=open("./temp/test",O_WRONLY);
if(fd==-1){
perror("fail");
return -1;
}
while(1){
write(fd,buf,strlen(buf));
sleep(1);
}
}
System V消息队列
System V信号量
内存映射
通过mmap将文件或者设备使用到的物理地址映射到进程的虚拟地址空间,通过返回的指针即可直接操作物理地址上的数据。底层是通过页表来实现虚拟地址到物理地址的映射,每个进程都有自己的页表,来管理地址的映射。
进程的虚拟地址空间的内核空间都映射到同一块物理内存上,并且通过MMU来管理,所以进程虚拟地址空间用户空间独立,内核空间共享。
System V共享内存
POSIX消息队列
POSIX消息队列底层为mqueue inode节点,该节点基于红黑树保存信息。
当进程用mq_open 打开文件名,就会找到对应的mqueue inode 。
POSIX信号量
无名信号量:常用于线程同步和互斥操作,因为线程之间共享同一个内存区
有名信号量:在文件系统中创建一个特殊文件,多个进程可以访问同一个命名信号量,并且可以通过信号量名称进行识别,用于进程同步和互斥。