内存控制函数(1)-mmap() 建立内存映射
示例1:
1.首先建立一个文本文件,名字为tmp,内容为hello world
2.编写mmap.c
#include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/mman.h> int main() { int fd, len; int *p; fd = open("tmp", O_RDWR); if (fd < 0) { perror("open"); exit(1); } len = lseek(fd, 0, SEEK_END); // 第一个参数代表内存起始地址,设为NULL代表让系统自动选定地址 p = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); if (p == MAP_FAILED) { perror("mmap"); exit(1); } // 如果映射成功,修改p[0] p[0] = 0x30313233; close(fd); // 释放内存映射地址 munmap(p, len); return 0; }
3.运行,并查看tmp内容
od -tx1 -tc tmp
0000000 33 32 31 30 6f 20 77 6f 72 6c 64 0a
3 2 1 0 o w o r l d \n
0000014
磁盘文件tmp的内容已被修改.
示例2:利用mmap实现进程间通信
process_mmap_w.c
/* process_mmap_w.c */ #include <stdlib.h> #include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #include <sys/mman.h> #define MAPLEN 0X1000 struct STU { int id; char name[20]; char sex; }; void sys_error(char *str, int exitno) { perror(str); exit(exitno); } int main(int argc, char *argv[]) { struct STU *mm; int fd, i = 0; if(argc < 2) { printf("Need filename! \n"); exit(1); } fd = open(argv[1], O_RDWR | O_CREAT, 0777); if (fd < 0) sys_error("open", 1); if (lseek(fd, MAPLEN-1, SEEK_SET) < 0) sys_error("lseek", 3); if (write(fd, "\0", 1) < 0) sys_error("write", 4); mm = mmap(NULL, MAPLEN, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); if (mm == MAP_FAILED) sys_error("mmap", 2); close(fd); while(1) { mm->id = i; sprintf(mm->name, "zhang-%d", i); if (i%2 == 0) mm->sex = 'm'; else mm->sex = 'w'; i++; sleep(1); } munmap(mm, MAPLEN); return 0; }
process_mmap_r.c
#include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #include <sys/mman.h> #define MAPLEN 0x1000 struct STU { int id; char name[20]; char sex; }; void sys_err(char *str, int exitno) { perror(str); exit(exitno); } int main(int argc, char *argv[]) { int fd; struct STU *mm; if (argc < 2) { printf("Need input filename\n"); exit(1); } fd = open(argv[1], O_RDWR); if (fd < 0) sys_err("open", 1); mm = mmap(NULL, MAPLEN, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); if (mm == MAP_FAILED) sys_err("mmap", 2); close(fd); unlink(argv[1]); while(1) { printf("%d\n", mm->id); printf("%s\n", mm->name); printf("%c\n", mm->sex); sleep(1); } munmap(mm, MAPLEN); return 0; }
运行两个进程:
10
zhang-10
m
11
zhang-11
w
12
zhang-12
m
13
zhang-13
w
14
zhang-14
m
如果您觉得阅读本文对您有帮助,请点一下“推荐”按钮,您的“推荐”将是我最大的写作动力!欢迎各位转载,但是未经作者本人同意,转载文章之后必须在文章页面明显位置给出作者和原文连接,否则保留追究法律责任的权利。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库