mmap详解,android零基础入门

#include <unistd.h>

#include <error.h>

#define BUF_SIZE 100

int main(int argc, char **argv)

{

int fd, nread, i;

struct stat sb;

char *mapped, buf[BUF_SIZE];

for (i = 0; i < BUF_SIZE; i++) {

buf[i] = ‘#’;

}

/* 打开文件 */

if ((fd = open(argv[1], O_RDWR)) < 0) {

perror(“open”);

}

/* 获取文件的属性 */

if ((fstat(fd, &sb)) == -1) {

perror(“fstat”);

}

/* 将文件映射至进程的地址空间 */

if ((mapped = (char *)mmap(NULL, sb.st_size, PROT_READ |

PROT_WRITE, MAP_SHARED, fd, 0)) == (void *)-1) {

perror(“mmap”);

}

/* 映射完后, 关闭文件也可以操纵内存 */

close(fd);

printf(“%s”, mapped);

/* 修改一个字符,同步到磁盘文件 */

mapped[20] = ‘9’;

if ((msync((void *)mapped, sb.st_size, MS_SYNC)) == -1) {

perror(“msync”);

}

/* 释放存储映射区 */

if ((munmap((void *)mapped, sb.st_size)) == -1) {

perror(“munmap”);

}

return 0;

}

2 私有映射无法修改文件

/* 将文件映射至进程的地址空间 */

if ((mapped = (char *)mmap(NULL, sb.st_size, PROT_READ |

PROT_WRITE, MAP_PRIVATE, fd, 0)) == (void *)-1) {

perror(“mmap”);

}

五. 使用共享映射实现两个进程之间的通信

两个程序映射同一个文件到自己的地址空间, 进程A先运行, 每隔两秒读取映射区域, 看是否发生变化.

进程B后运行, 它修改映射区域, 然后推出, 此时进程A能够观察到存储映射区的变化

进程A的代码:

C代码

#include <sys/mman.h>

#include <sys/stat.h>

#include <fcntl.h>

#include <stdio.h>

#include <stdlib.h>

#include <unistd.h>

#include <error.h>

#define BUF_SIZE 100

int main(int argc, char **argv)

{

int fd, nread, i;

struct stat sb;

char *mapped, buf[BUF_SIZE];

for (i = 0; i < BUF_SIZE; i++) {

buf[i] = ‘#’;

}

/* 打开文件 */

if ((fd = open(argv[1], O_RDWR)) < 0) {

perror(“open”);

}

/* 获取文件的属性 */

if ((fstat(fd, &sb)) == -1) {

perror(“fstat”);

}

/* 将文件映射至进程的地址空间 */

if ((mapped = (char *)mmap(NULL, sb.st_size, PROT_READ |

PROT_WRITE, MAP_SHARED, fd, 0)) == (void *)-1) {

perror(“mmap”);

}

/* 文件已在内存, 关闭文件也可以操纵内存 */

close(fd);

/* 每隔两秒查看存储映射区是否被修改 */

while (1) {

printf(“%s\n”, mapped);

sleep(2);

}

return 0;

}

进程B的代码:

C代码

#include <sys/mman.h>

#include <sys/stat.h>

#include <fcntl.h>

#include <stdio.h>

#include <stdlib.h>

#include <unistd.h>

#include <error.h>

#define BUF_SIZE 100

int main(int argc, char **argv)

{

int fd, nread, i;

struct stat sb;

char *mapped, buf[BUF_SIZE];

for (i = 0; i < BUF_SIZE; i++) {

buf[i] = ‘#’;

}

/* 打开文件 */

if ((fd = open(argv[1], O_RDWR)) < 0) {

perror(“open”);

}

/* 获取文件的属性 */

if ((fstat(fd, &sb)) == -1) {

perror(“fstat”);

}

/* 私有文件映射将无法修改文件 */

if ((mapped = (char *)mmap(NULL, sb.st_size, PROT_READ |

PROT_WRITE, MAP_PRIVATE, fd, 0)) == (void *)-1) {

perror(“mmap”);

}

/* 映射完后, 关闭文件也可以操纵内存 */

close(fd);

/* 修改一个字符 */

mapped[20] = ‘9’;

return 0;

}

六. 通过匿名映射实现父子进程通信

C代码

#include <sys/mman.h>

#include <stdio.h>

#include <stdlib.h>

#include <unistd.h>

#define BUF_SIZE 100

int main(int argc, char** argv)

{

char *p_map;

/* 匿名映射,创建一块内存供父子进程通信 */

p_map = (char *)mmap(NULL, BUF_SIZE, PROT_READ | PROT_WRITE,

MAP_SHARED | MAP_ANONYMOUS, -1, 0);

if(fork() == 0) {

sleep(1);

printf(“child got a message: %s\n”, p_map);

sprintf(p_map, “%s”, “hi, dad, this is son”);

munmap(p_map, BUF_SIZE); //实际上,进程终止时,会自动解除映射。

exit(0);

}

sprintf(p_map, “%s”, “hi, this is father”);

sleep(2);

printf(“parent got a message: %s\n”, p_map);

return 0;

}

七. 对mmap()返回地址的访问

linux采用的是页式管理机制。对于用mmap()映射普通文件来说,进程会在自己的地址空间新增一块空间,空间大

小由mmap()的len参数指定,注意,进程并不一定能够对全部新增空间都能进行有效访问。进程能够访问的有效地址大小取决于文件被映射部分的大小。简单的说,能够容纳文件被映射部分大小的最少页面个数决定了进程从mmap()返回的地址开始,能够有效访问的地址空间大小。超过这个空间大小,内核会根据超过的严重程度返回发送不同的信号给进程。可用如下图示说明:

总结一下就是, 文件大小, mmap的参数 len 都不能决定进程能访问的大小, 而是容纳文件被映射部分的最小页面数决定

进程能访问的大小. 下面看一个实例:

C代码

#include <sys/mman.h>
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则近万的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

img

img

img

img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:Android)

尾声

如果你想成为一个优秀的 Android 开发人员,请集中精力,对基础和重要的事情做深度研究。

对于很多初中级Android工程师而言,想要提升技能,往往是自己摸索成长,不成体系的学习效果低效漫长且无助。 整理的这些架构技术希望对Android开发的朋友们有所参考以及少走弯路,本文的重点是你有没有收获与成长,其余的都不重要,希望读者们能谨记这一点。

这里,笔者分享一份从架构哲学的层面来剖析的视频及资料分享给大家梳理了多年的架构经验,筹备近6个月最新录制的,相信这份视频能给你带来不一样的启发、收获。

PS:之前因为秋招收集的二十套一二线互联网公司Android面试真题 (含BAT、小米、华为、美团、滴滴)和我自己整理Android复习笔记(包含Android基础知识点、Android扩展知识点、Android源码解析、设计模式汇总、Gradle知识点、常见算法题汇总。)

架构篇

《Jetpack全家桶打造全新Google标准架构模式》

《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!

视频及资料分享给大家梳理了多年的架构经验,筹备近6个月最新录制的,相信这份视频能给你带来不一样的启发、收获。[外链图片转存中…(img-EnCZXPoy-1712786544757)]

PS:之前因为秋招收集的二十套一二线互联网公司Android面试真题 (含BAT、小米、华为、美团、滴滴)和我自己整理Android复习笔记(包含Android基础知识点、Android扩展知识点、Android源码解析、设计模式汇总、Gradle知识点、常见算法题汇总。)

[外链图片转存中…(img-3WRgJ7g8-1712786544757)]

架构篇

《Jetpack全家桶打造全新Google标准架构模式》
[外链图片转存中…(img-iZD8eUQs-1712786544757)]

《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!

  • 27
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值