当前位置: 首页 > news >正文

Linux系统编程 day6 进程间通信mmap

父子共享的信息:文件描述符,mmap建立的共享映射区(MAP_SHARED)

mmap父子间进程通信

var的时候 :读时共享,写时复制

父进程先创建映射区,指定共享MAP_SHARED权限 , fork创建子进程。

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<pthread.h>
#include<sys/mman.h>
#include<fcntl.h>
#include<sys/wait.h>
int var = 100;
int main(int argc , char *argv[])
{int fd;pid_t pid;int *p;fd = open("text" , O_RDWR|O_CREAT|O_TRUNC , 0644);if(fd == -1){perror("open error");exit(1);}ftruncate(fd , 4);p = (int*)mmap(NULL, 4 , PROT_READ|PROT_WRITE , MAP_SHARED , fd , 0);if(p == MAP_FAILED){perror("mmap error");exit(1);}pid = fork();if(pid == 0){*p = 2000;   //写共享内存var = 1000;  printf("I am child,mypid:%d , *p = %d , var = %d\n" , getpid() , *p ,var);}else{sleep(1);printf("I am parent , *p = %d , var = %d\n" , *p , var);wait(NULL);int ret = munmap(p , 4);if(ret == -1){perror("munmap error");exit(1);}}return 0 ;
}

mmap无血缘关系进程间通信(重点)

两个进程打开同一个文件,创建映射区,指定flags为MAP_SHARED,一个进程写入一个进程读出。效率应该是最高的。 

为什么会映射到同一块内存上,借用GPT:即使两个没有血缘关系(即非父子关系)的进程,分别 open() 同一个文件,然后使用 mmap() 映射这同一个文件,得到的指针 p(虚拟地址)**可能不同,但它们最终指向的是同一块 物理内存页,因为 mmap 的核心是文件映射到物理页帧,多个进程映射相同文件内容,就映射到了同一块物理内存。

写端:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<pthread.h>
#include<sys/mman.h>
#include<fcntl.h>
#include<sys/wait.h>struct student{int id ;char name[256];int age;
};int main(int argc , char *argv[])
{struct student stu = {1 , "xiaoming" , 19};int fd;int *p;fd = open("textw" , O_RDWR|O_CREAT|O_TRUNC , 0644);ftruncate(fd , sizeof(stu));printf("fdwrite:%d\n",fd);p = mmap(NULL, sizeof(stu) , PROT_READ|PROT_WRITE , MAP_SHARED , fd , 0);if(p == MAP_FAILED){perror("mmap error");exit(1);}close(fd);while(1){sleep(1);memcpy(p ,&stu ,sizeof(stu));stu.id++;}munmap(p , sizeof(stu));return 0;
}

读端:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<pthread.h>
#include<sys/mman.h>
#include<fcntl.h>
#include<sys/wait.h>struct student{int id ;char name[256];int age;
};int main(int argc , char *argv[])
{struct student stu;int fd;struct student *p;fd = open("textw" , O_RDWR);printf("fd read: %d\n" , fd);p = mmap(NULL, sizeof(stu) , PROT_READ|PROT_WRITE , MAP_SHARED , fd , 0);if(p == MAP_FAILED){perror("mmap error");exit(1);}close(fd);while(1){printf("id:%d , name:%s , age:%d\n" , p->id , p->name , p->age);sleep(1);}munmap(p , sizeof(stu));return 0;
}

注意:无血缘关系进程间通信。FIFO:数据只能一次读取

mmap:数据可以重复读取。

匿名映射(了解)

void* mmap(NULL , size , PROT_READ|PROT_WRITE , MAP_SHARED|MAP_ANON , -1 ,0);size: 可以随便写
flags:需要写MAP_ANON
fd : -1

相关文章:

  • 借助LlamaIndex实现简单Agent
  • Day2—3:前端项目uniapp壁纸实战
  • 深入理解 MCP 协议:开启 AI 交互新时代
  • 【人工智能】再谈探索AI幻觉及其解决方案(进一步整理)
  • 信创开发:开启信息自主创新、国产替代新时代
  • [Java微服务组件]注册中心P3-Nacos中的设计模式1-观察者模式
  • mysql控制单表数据存储及单实例表创建
  • 生物化学笔记:医学免疫学原理23 免疫检查点分子与肿瘤免疫治疗(PD-1抑制剂黑色素瘤)
  • 【进程信号】五、信号集操作接口详解
  • SICAR标准功能块 FB1514 “Robot_request_FB”
  • 增量式PID基础解析与代码实例:温控系统
  • 有效的完全平方数--LeetCode
  • HFSS3(limy)——建模学习记录
  • 工业级MIFI解决方案:打造低时延、高可靠性的Wi-Fi网络快速部署体系!
  • 【专刷】滑动窗口(一)
  • 字符串系列一>二进制求和
  • HTML5+CSS3小实例:CSS立方体
  • 在RK3588上使用哪个流媒体服务器合适
  • 性能比拼: Elixir vs Go(第二轮)
  • JAVA的泛型
  • 拒绝“假期刺客”,澎湃启动“五一”消费维权线索征集
  • 不降息就走人?特朗普试图开先例罢免美联储主席,有无胜算
  • 地铁口被吐槽像棺材?杭州地铁公司回应:是一个标志性出入口
  • 首季中国经济观察:一季度社融增量超15万亿元传递积极信号
  • 陈吉宁龚正深入郊区镇村园区调研乡村振兴并召开现场会,明确这些重点工作
  • 应急部:一季度全国各类生产安全事故总量同比下降29.5%