10.进程间通信(五)
一.上集回顾
建议先学上篇博客,再向下学习,上篇博客的链接如下:
https://blog.csdn.net/weixin_60668256/article/details/154432998?fromshare=blogdetail&sharetype=blogdetail&sharerId=154432998&sharerefer=PC&sharesource=weixin_60668256&sharefrom=from_link
二.消息队列介绍



三.消息队列的接口(和共享内存相似)




![]()
删除的cmd也和共享内存是一样的
查询消息队列:

删除操作

消息队列和共享内存的接口大部分都是一样的
四.消息队列的接口(和共享内存不相似)
共享内存,我们可以直接使用printf等接口之间进行操作,但是消息队列不行


五.system V信号量

1.并发编程,概念铺垫




2.信号量




这两个本质上就是一回事
![]()
![]()



后续我们在进行实操
3.System V是如何实现IPC的?和管道为什么不同呢?
a.应用角度,看IPC属性





key的构成全部都是路径 + 项目ID
我们以共享内存为例,来获取一些共享内存的属性:


void ShmMeta(){struct shmid_ds buffer;//系统提供的数据类型int n = shmctl(_shmid,IPC_STAT,&buffer);if(n < 0){return;}std::cout << "#######################" << std::endl;std::cout << "buffer.shm_atime" << buffer.shm_atime << std::endl;std::cout << "buffer.shm_cpid" << buffer.shm_cpid << std::endl;std::cout << "buffer.shm_ctime" << buffer.shm_ctime << std::endl;std::cout << "buffer.shm_nattch" << buffer.shm_nattch << std::endl;std::cout << "buffer.shm_perm.__key" << ToHex(buffer.shm_perm.__key) << std::endl;std::cout << "#######################" << std::endl;}

这里就能获取我们对应的共享内存的信息
b.内核角度,看IPC结构
![]()












我们用start和end进行映射,再将vm_file和文件通过mmap进行关联,就能实现用指针进行写入文件

我们可以使用mmap这个接口来实现一个代码demo
#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>int main() {// 1. 打开(或创建)文件int fd = open("mmap_demo.txt", O_RDWR | O_CREAT | O_TRUNC, 0666);if (fd == -1) {perror("open");exit(1);}// 2. 扩展文件大小(确保有足够空间映射)const int size = 4096; // 映射大小(通常为页大小的整数倍,如4096字节)if (ftruncate(fd, size) == -1) {perror("ftruncate");close(fd);exit(1);}// 3. 内存映射:将文件映射到进程内存空间// 参数:映射起始地址(NULL表示由系统分配)、映射大小、权限、映射标志、文件描述符、文件偏移char *addr = (char *)mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);if (addr == MAP_FAILED) {perror("mmap");close(fd);exit(1);}// 4. 关闭文件描述符(映射后可关闭,不影响内存映射)close(fd);// 5. 对映射内存进行读写操作strcpy(addr, "Hello, mmap! 这是映射文件的内容。");printf("写入内存的内容:%s\n", addr);// 6. 解除内存映射if (munmap(addr, size) == -1) {perror("munmap");exit(1);}printf("内存映射已解除,可查看 mmap_demo.txt 文件验证内容\n");return 0;
}


4.总结




进程间通信这里,我们只需要见过命名管道,匿名管道,共享内存(信号量,消息队列不考虑)
