Linux mmap内存映射

article/2025/10/23 10:26:25

一、什么是mmap

mmap是一种内存映射文件的方法,即将一个文件或者其它对象映射到进程的地址空间,实现文件磁盘地址和进程虚拟地址空间中一段虚拟地址的一一对映关系,函数原型如下

void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset);

实现这样的映射关系后,进程就可以采用指针的方式读写操作这一段内存,而系统会自动回写脏页面到对应的文件磁盘上,即完成了对文件的操作而不必再调用read,write等系统调用函数。如下图所示

mmap除了可以减少read,write等系统调用以外,还可以减少内存的拷贝次数,比如在read调用时,一个完整的流程是操作系统读磁盘文件到页缓存,再从页缓存将数据拷贝到read传递的buffer里,而如果使用mmap之后,操作系统只需要将磁盘读到页缓存,然后用户就可以直接通过指针的方式操作mmap映射的内存,减少了从内核态到用户态的数据拷贝。

mmap适合于对同一块区域频繁读写的情况,比如一个64M的文件存储了一些索引信息,我们需要频繁修改并持久化到磁盘,这样可以将文件通过mmap映射到用户虚拟内存,然后通过指针的方式修改内存区域,由操作系统自动将修改的部分刷回磁盘,也可以自己调用msync手动刷磁盘。

内核角度分析mmap原理,这篇博客图文并茂,直接参考就好了。

linux内存映射mmap原理分析 - 鱼思故渊的专栏 - CSDN博客 blog.csdn.net/yusiguyuan/…

映射只不过是映射到虚拟内存,不用担心映射的文件太大。

每个进程的4G内存空间只是虚拟内存空间,每次访问内存空间的某个地址,都需要把地址翻译为实际物理内存地址

所有进程共享同一物理内存,每个进程只把自己目前需要的虚拟内存空间映射并存储到物理内存上。

详细虚拟内存的内容还是参考大神总结

linux 进程的虚拟内存 - fengxin的博客 - CSDN博客 blog.csdn.net/fengxinlinu…

二、mmap参数说明

映射文件或设备到内存中,取消映射就是munmap函数。

语法如下:

void *mmap(void *addr, size_t length, int prot, int flags,

int fd, off_t offset);

int munmap(void *addr, size_t length);

该函数主要用途有三个:

将普通文件映射到内存中,通常在需要对文件进行频繁读写时使用,用内存读写取代I/O读写,以获得较高的性能;

将特殊文件进行匿名内存映射,为关联进程提供共享内存空间;

为无关联的进程间的Posix共享内存(SystemV的共享内存操作是shmget/shmat)

我们来看下函数的入参选择:

➢ 参数addr:

指向欲映射的内存起始地址,通常设为 NULL,代表让系统自动选定地址,映射成功后返回该地址。

➢ 参数length:

代表将文件中多大的部分映射到内存。

➢ 参数prot:

映射区域的保护方式。可以为以下几种方式的组合:

PROT_EXEC 映射区域可被执行

PROT_READ 映射区域可被读取

PROT_WRITE 映射区域可被写入

PROT_NONE 映射区域不能存取

➢ 参数flags:

影响映射区域的各种特性。在调用mmap()时必须要指定MAP_SHARED 或MAP_PRIVATE。

MAP_FIXED 如果参数start所指的地址无法成功建立映射时,则放弃映射,不对地址做修正。通常不鼓励用此。

MAP_SHARED对映射区域的写入数据会复制回文件内,而且允许其他映射该文件的进程共享。

MAP_PRIVATE 对映射区域的写入操作会产生一个映射文件的复制,即私人的“写入时复制”(copy on write)对此区域作的任何修改都不会写回原来的文件内容。

MAP_ANONYMOUS建立匿名映射。此时会忽略参数fd,不涉及文件,而且映射区域无法和其他进程共享。

MAP_DENYWRITE只允许对映射区域的写入操作,其他对文件直接写入的操作将会被拒绝。

MAP_LOCKED 将映射区域锁定住,这表示该区域不会被置换(swap)。

➢ 参数fd:

要映射到内存中的文件描述符。如果使用匿名内存映射时,即flags中设置了MAP_ANONYMOUS,fd设为-1。

➢ 参数offset:

文件映射的偏移量,通常设置为0,代表从文件最前方开始对应,offset必须是分页大小的整数倍。

返回说明

成功执行时,mmap()返回被映射区的指针,munmap()返回0。失败时,mmap()返回MAP_FAILED[其值为(void *)-1],munmap返回-1。errno被设为以下的某个值。

EACCES:访问出错

EAGAIN:文件已被锁定,或者太多的内存已被锁定

EBADF:fd不是有效的文件描述词

EINVAL:一个或者多个参数无效

ENFILE:已达到系统对打开文件的限制

ENODEV:指定文件所在的文件系统不支持内存映射

ENOMEM:内存不足,或者进程已超出最大内存映射数量

EPERM:权能不足,操作不允许

ETXTBSY:已写的方式打开文件,同时指定MAP_DENYWRITE标志

SIGSEGV:试着向只读区写入

SIGBUS:试着访问不属于进程的内存区

三、mmap与直接IO(read、write)的效率比较

不能简单的说哪个效率高,要看具体实现与具体应用。

write read mmap实际流程如下:

无论是通过mmap方式或read/write方式访问文件在内核中都必须经过两个缓存:一个是用address_space来组织的以页为基础的缓存;一个是以buffer来组织的缓存,但实际上这两个缓存只是同一个缓冲池里内容的不同组织方式。当需要从文件读写内容时,都经过 address_space_operation中提供的函数也就是说路径是一致的。如果是用read/write方式,用户须向内核指定要读多少,内核再把得到的内容从内核缓冲池拷向用户空间;写也须要有一个大致如此的过程。

mmap的优势在于通过把文件的某一块内容映射到用户空间上,用户可以直接向内核缓冲池读写这一块内容,这样一来就少了内核与用户空间的来回拷贝所以通常更快。但 mmap方式只适用于更新、读写一块固定大小的文件区域而不能做像诸如不断的写内容进入文件导到文件增长这类的事。

二者的主要区别在于,与mmap和memcpy相比,read和write执行了更多的系统调用,并做了更多的复制。read和write将数据从内核缓冲区中复制到应用缓冲区,然后再把数据从应用缓冲区复制到内核缓冲区。而mmap和memcpy则直接把数据从映射到地址空间的一个内核缓冲区复制到另一个内核缓冲区。当引用尚不存在的内存页时,这样的复制过程就会作为处理页错误的结果而出现(每次错页读发生一次错误,每次错页写发生一次错误)。

所以他们两者的效率的比较就是系统调用和额外的复制操作的开销和页错误的开销之间的比较,哪一个开销少就是哪一个表现更好。用mmap可以避免与读写打交道,这样可以简化程序逻辑,有利于编程实现。

系统调用mmap()可以将某文件映射至内存(进程空间),如此可以把对文件的操作转为对内存的操作,以此避免更多的lseek()与read()、write()操作,这点对于大文件或者频繁访问的文件而言尤其受益。但有一点必须清楚:mmap的addr与offset必须对齐一个内存页面大小的边界,即内存映射往往是页面大小的整数倍,否则maaped_file_size%page_size内存空间将被闲置浪费。映射时,指定offset最好是内存页面大小的整数倍。

内存文件映射的使用:

(1)大数据量文件的读取,有效的提高磁盘和内存间数据通信的性能;

(2)进程间快速的共享内存,实现进程间高效的通信。

内存映射文件性能高于普通IO的原因:

内存文件映射和普通的文件IO都是要通过文件系统和硬盘驱动拷贝数据到内存中,内存文件映射数据越大越快主要是:

(1)实际拷贝数据前,需要建立映射信息,内存文件映射已经提前准备好了映射关系,内核调度好了进程内的内存块,交付给内核进行了预先处理,内存文件映射会消耗掉一些时间。

(2)实际拷贝时候,内存文件映射将磁盘数据直接拷贝到用户进程内存空间只进行了一次拷贝,而普通的IO是先将文件拷贝到内核缓存空间 ,然后才拷贝到用户进程内存空间,进行了两次拷贝。

下面是一个使用普通的fread函数和内存映射文件函数,读取不同大小的磁盘文件的性能分析表:

综合:

当读写磁盘文件的数据较小(少于1MB)时候,使用内存文件映射和普通IO是差异很小的,所以建议使用普通IO就可以了;当很多文件的大小在几十MB, 几百MB, 或者1GB以上的文件数据需要进行较频繁的访问,或者一开始需要全部加载这些大文件的时候,那么就需要考虑使用内存文件映射了。

【文章福利】小编推荐自己的Linux内核技术交流群: 【977878001】整理一些个人觉得比较好得学习书籍、视频资料!进群私聊管理领取 内核资料包(含视频教程、电子书、实战项目及代码)

内核资料直通车:Linux内核源码技术学习路线+视频教程代码资料

学习直通车:Linux内核源码/内存调优/文件系统/进程管理/设备驱动/网络协议栈

四、网上测试实例

(1)demo1

演示一下,将文件/tmp/file_mmap中的字符转成大写,分别使用mmap与read/write二种方法实现。

先创建/tmp/file_mmap文件,该文件写入www.baidu.com,使用strace统计系统调用。

/*
* @file: t_mmap.c
*/
#include <stdio.h>
#include <ctype.h>
#include <sys/mman.h> /*mmap munmap*/
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>int main(int argc, char *argv[])
{int fd;char *buf;off_t len;struct stat sb;char *fname = "/tmp/file_mmap";fd = open(fname, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);if (fd == -1){perror("open");return 1;}if (fstat(fd, &sb) == -1){perror("fstat");return 1;}buf = mmap(0, sb.st_size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);if (buf == MAP_FAILED){perror("mmap");return 1;}if (close(fd) == -1){perror("close");return 1;}for (len = 0; len < sb.st_size; ++len){buf[len] = toupper(buf[len]);/*putchar(buf[len]);*/}if (munmap(buf, sb.st_size) == -1){perror("munmap");return 1;}return 0;
}

自己测试运行结果:

root@chenwr-pc:/home/workspace/test# gcc tmp.c -o run 
root@chenwr-pc:/home/workspace/test# strace ./run 
execve("./run", ["./run"], [/* 22 vars */]) = 0
brk(0)                                  = 0x1ffa000
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=106932, ...}) = 0
mmap(NULL, 106932, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7fcab05de000
close(3)                                = 0
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
open("/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0P \2\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=1857312, ...}) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fcab05dd000
mmap(NULL, 3965632, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7fcab000e000
mprotect(0x7fcab01cc000, 2097152, PROT_NONE) = 0
mmap(0x7fcab03cc000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1be000) = 0x7fcab03cc000
mmap(0x7fcab03d2000, 17088, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7fcab03d2000
close(3)                                = 0
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fcab05db000
arch_prctl(ARCH_SET_FS, 0x7fcab05db740) = 0
mprotect(0x7fcab03cc000, 16384, PROT_READ) = 0
mprotect(0x600000, 4096, PROT_READ)     = 0
mprotect(0x7fcab05f9000, 4096, PROT_READ) = 0
munmap(0x7fcab05de000, 106932)          = 0
open("/tmp/file_mmap", O_RDWR|O_CREAT, 0600) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=14, ...}) = 0
mmap(NULL, 14, PROT_READ|PROT_WRITE, MAP_SHARED, 3, 0) = 0x7fcab05f8000
close(3)                                = 0
munmap(0x7fcab05f8000, 14)              = 0
exit_group(0)                           = ?
+++ exited with 0 +++

该文件已经变成大写。

root@chenwr-pc:/tmp# cat file_mmap 
WWW.BAIDU.COM

网上该demo的说明:

open("/tmp/file_mmap", O_RDWR|O_CREAT, 0600) = 3 //open,返回fd=3
fstat64(3, {st_mode=S_IFREG|0644, st_size=18, ...}) = 0 //fstat, 即文件大小18
mmap2(NULL, 18, PROT_READ|PROT_WRITE, MAP_SHARED, 3, 0) = 0xb7867000 //mmap文件fd=3
close(3)  = 0 //close文件fd=3
munmap(0xb7867000, 18)= 0  //munmap,移除0xb7867000这里的内存映射
这里mmap的addr是0(NULL),offset是18,并不是一个内存页的整数倍,即有4078bytes(4kb-18)内存空间被闲置浪费了。

(2)demo2 read的方式

#include <stdio.h>
#include <ctype.h>
#include <sys/mman.h> /*mmap munmap*/
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>int main(int argc, char *argv[])
{int fd, len;char *buf;char *fname = "/tmp/file_mmap";ssize_t ret;struct stat sb;fd = open(fname, O_CREAT|O_RDWR, S_IRUSR|S_IWUSR);if (fd == -1){perror("open");return 1;}if (fstat(fd, &sb) == -1){perror("stat");return 1;}buf = malloc(sb.st_size);if (buf == NULL){perror("malloc");return 1;}ret = read(fd, buf, sb.st_size);for (len = 0; len < sb.st_size; ++len){buf[len] = toupper(buf[len]);/*putchar(buf[len]);*/}lseek(fd, 0, SEEK_SET);ret = write(fd, buf, sb.st_size);if (ret == -1){perror("error");return 1;}if (close(fd) == -1){perror("close");return 1;
}
free(buf);return 0;
}

自己测试运行的结果:

root@chenwr-pc:/home/workspace/test# strace ./run 
execve("./run", ["./run"], [/* 22 vars */]) = 0
brk(0)                                  = 0x13ac000
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=106932, ...}) = 0
mmap(NULL, 106932, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7fb98f1d7000
close(3)                                = 0
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
open("/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0P \2\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=1857312, ...}) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fb98f1d6000
mmap(NULL, 3965632, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7fb98ec07000
mprotect(0x7fb98edc5000, 2097152, PROT_NONE) = 0
mmap(0x7fb98efc5000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1be000) = 0x7fb98efc5000
mmap(0x7fb98efcb000, 17088, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7fb98efcb000
close(3)                                = 0
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fb98f1d4000
arch_prctl(ARCH_SET_FS, 0x7fb98f1d4740) = 0
mprotect(0x7fb98efc5000, 16384, PROT_READ) = 0
mprotect(0x600000, 4096, PROT_READ)     = 0
mprotect(0x7fb98f1f2000, 4096, PROT_READ) = 0
munmap(0x7fb98f1d7000, 106932)          = 0
open("/tmp/file_mmap", O_RDWR|O_CREAT, 0600) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=14, ...}) = 0
brk(0)                                  = 0x13ac000
brk(0x13cd000)                          = 0x13cd000
read(3, "www.baidu.com\n", 14)          = 14
lseek(3, 0, SEEK_SET)                   = 0
write(3, "WWW.BAIDU.COM\n", 14)         = 14
close(3)                                = 0
exit_group(0)                           = ?
+++ exited with 0 +++

网上该demo的说明:

open("/tmp/file_mmap", O_RDWR|O_CREAT, 0600) = 3 //open, fd=3
fstat64(3, {st_mode=S_IFREG|0644, st_size=18, ...}) = 0 //fstat, 其中文件大小18
brk(0) = 0x9845000  //brk, 返回当前中断点
brk(0x9866000)  = 0x9866000  //malloc分配内存,堆当前最后地址
read(3, "www.perfgeeks.com\n", 18)= 18 //read
lseek(3, 0, SEEK_SET) = 0 //lseek
write(3, "WWW.PERFGEEKS.COM\n", 18)  = 18 //write
close(3)  = 0

这里通过read()读取文件内容,toupper()后,调用write()写回文件。因为文件太小,体现不出read()/write()的缺点:频繁访问大文件,需要多个lseek()来确定位置。每次编辑read()/write(),在物理内存中的双份数据。

当然,不可以忽略创建与维护mmap()数据结构的成本。需要注意:并没有具体测试mmap vs read/write,即不能一语断言谁孰谁劣,具体应用场景具体评测分析。

你只是要记住:mmap内存映射文件之后,操作内存即是操作文件,可以省去不少系统内核调用(lseek, read, write)。

五、自己写的demo

#include <stdio.h>
#include <ctype.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <time.h>
#define INT64U          unsigned long long #define MSG_ERR     1
#define MSG_WARN    2
#define MSG_INFO    3
#define MSG_DBG     4
#define MSG_NOR     5#define MSG_HEAD     ("libfat->")
#define PRTMSG(level, fmt, args...)\
do {\if (level <= MSG_NOR) {\if (level <= MSG_NOR) {\printf("%s, %s, line %d: " fmt,__FILE__,__FUNCTION__,__LINE__, ##args);\} else {\printf("%s:" fmt, MSG_HEAD, ##args);\}\}\
} while(0)typedef unsigned char       BOOLEAN;
typedef unsigned char       INT8U;
typedef unsigned int        INT16U;
typedef unsigned long       INT32U;typedef signed char         INT8S;
typedef signed int          INT16S;
typedef signed long         INT32S;char *filename = "./lt00001";
//char *filename = "/mnt/sdisk/video/lt00004";
char *data = "1111111111\
2222222222\
3333333333\
4444444444";
INT32S data_len = 40;//单次写入的数据长度
struct timeval t_start, t_end;
struct stat file_info;
long cost_time = 0;
int write_num = 1000;INT32S mmap_write(INT32S fd, INT64U offset, void *data, INT32S data_len)
{char *buf = NULL;if (fstat(fd, &file_info) == -1) {perror("fstat");PRTMSG(MSG_ERR, "[cwr] Get file info failed\n");return -1;}buf = mmap(0, file_info.st_size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);if (buf == MAP_FAILED) {perror("mmap");PRTMSG(MSG_ERR, "[cwr] mmap failed\n");return -1;} //offset = (INT64U)((order)*sizeof(FAT_FILE_LIST_T));memcpy(buf+offset, data, data_len);if (munmap(buf, file_info.st_size) == -1) {perror("munmap");PRTMSG(MSG_ERR, "[cwr] munmap failed\n");return -1;}return data_len;
}
int write_test()
{int fd, ret, i, data_size;INT64U ret64, offset;int ret_len = 0;time_t starttime, endtime;fd = open(filename, O_RDWR);if (fd < 0) {printf("[cwr] open file faild\n");}gettimeofday(&t_start, NULL);for (i=0; i<write_num; i++) {offset = i*data_len;ret64 = lseek64(fd, offset, SEEK_SET);if (ret64 == -1LL) {printf("lseek data fail\n");return -1;}ret_len = write(fd, data, data_len);if (ret_len != data_len) {printf("[cwr] count = %d; write error\n", i);close(fd);return -1;}}gettimeofday(&t_end, NULL);printf("[cwr] test end, count = %d\n", i);close(fd);return 0;
}
int mmap_write_test()
{int fd, ret, i, data_size;INT64U ret64, offset;int ret_len = 0;fd = open(filename, O_RDWR);if (fd < 0) {printf("[cwr] open file faild\n");}gettimeofday(&t_start, NULL);for (i=0; i<write_num; i++) {offset = i*data_len;ret_len = mmap_write(fd, offset, data, data_len);if (ret_len != data_len) {printf("[cwr] count = %d; mmap write error\n", i);close(fd);return -1;}}gettimeofday(&t_end, NULL);printf("[cwr] mmap write test end, count = %d\n", i);close(fd);return 0;}
void main()
{int ret;memset(&file_info, 0, sizeof(file_info));
#if 1ret = write_test();if (ret != 0) {printf("[cwr] write_test failed\n");}
#endif
#if 0ret = mmap_write_test();if (ret != 0) {printf("[cwr] mmap_write_test failed\n");}
#endifcost_time = t_end.tv_usec - t_start.tv_usec;printf("Start time: %ld us\n", t_start.tv_usec);printf("End time: %ld us\n", t_end.tv_usec);printf("Cost time: %ld us\n", cost_time);while(1) {sleep(1);}
}

运行结果:

write的方式获取的时间

使用mmap的方式去操作

后续不映射整个文件的空间大小,而是映射要写入数据的长度40字节

buf = mmap(0, 40, PROT_READ|PROT_WRITE, MAP_SHARED, fd, offset*4*1024)

为何测试mmap效率并没有更高效。


http://chatgpt.dhexx.cn/article/hEwXQpJX.shtml

相关文章

Linux下mmap

目录 一.mmap简介 二.为什么需要使用mmap 三.mmap的使用 四.mmap原理 一.mmap简介 什么是mmap了&#xff1f;从名字上来看是memory map也就是地址映射&#xff0c;是一种内存映射文件的方法。mmap是一个可以将一个文件或者其它对象映射到进程的地址空间实现磁盘的地址和进程虚…

Android 进程间通信机制(二) mmap 原理

一. 前言 Binder中一次拷贝的实现就是利用mmap(memory mapping)内存映射机制,我们来看看它的工作原理. 二. 参考文章 下面这几篇文章建议先好好阅读一下,都是总结的很好的文章, 每个人理解可能不一样 笔者也是看了好多博客文章和B站视频讲解, 然后加上自己的理解后 输出的一…

Linux mmap讲解

0 引言 Linux 提供了非常强大的 mmap(2) 系统调用&#xff1b; 它使开发人员能够将任何内容直接映射到进程虚拟地址空间 (VAS)。 此内容包括文件数据、硬件设备&#xff08;适配器&#xff09;内存区域&#xff0c;或只是通用内存区域。 在本文中&#xff0c;我们将只关注使用…

mmap内存映射

内存映射通信 一、mmap (memory_map) 1.1 简介 存储映射I/O (Memory-mapped I/O) 使一个磁盘文件与存储空间中的一个缓冲区相映射。于是当从缓冲区中取数据&#xff0c;就相当于读文件中的相应字节。于此类似&#xff0c;将数据存入缓冲区&#xff0c;则相应的字节就自动写入…

Linux编程之mmap示例

一、问题背景 Linux下&#xff0c;针对文件读写操作&#xff0c;一般有三个步骤&#xff1a; 1&#xff09;把文件内容读入到内存中&#xff1b;调用read&#xff08;系统调用&#xff09;&#xff0c;从内核态读取文件内容到虚拟内存&#xff1b; 2&#xff09;修改内存中的内…

【mmap】深度分析mmap:是什么 为什么 怎么用 性能总结

目录 有什么用&#xff1f; 1、文件映射 2、分配内存&#xff08;匿名文件映射&#xff09; mmap基础概念 mmap内存映射原理 mmap和常规文件操作的区别 mmap优点总结 mmap相关函数 mmap使用细节 性能总结 效率对比 有什么用&#xff1f; 将一个文件或者其它对象映射…

mmap使用

linux进程虚拟地址空间中存在一段称为mmap的内存区&#xff0c;当申请用户内存较大时&#xff0c;如大于128kb&#xff0c;系统一般会通过mmap系统调用直接映射一片内存区&#xff0c;使用结束后再通过ummap系统调用归还。关于mmap的原理网上有很多文档&#xff0c;这里不再赘述…

MMAP技术

1. mmap 基础概念 mmap 即 memory map&#xff0c;也就是内存映射。 mmap 是一种内存映射文件的方法&#xff0c;即将一个文件或者其它对象映射到进程的地址空间&#xff0c;实现文件磁盘地址和进程虚拟地址空间中一段虚拟地址的一一对映关系。实现这样的映射关系后&#xff…

mmap在嵌入式中的应用

大概雍正皇帝怎么也不会想到&#xff0c;自己在西历2022年的男生和女生眼里&#xff0c;会是截然不同的两种形象。 1 以我对身边同学朋友的观察&#xff0c;男生们大多爱看《雍正王朝》&#xff0c;他们眼中的雍正&#xff0c;大约是个推行了“火耗归公”、“摊丁入亩”等遏制…

Linux mmap原理

Linux mmap原理 前言Linux段页式内存管理mmapmmap内存映射原理文字概述mmap函数参数介绍源码解析1. 文件映射2. 缺页异常 mmap 和常规文件操作的区别mmap 使用的细节 小结 前言 mmap是linux操作系统提供给用户空间调用的内存映射函数&#xff0c;很多人仅仅只是知道可以通过mm…

Linux内存管理之mmap

目录 一. mmap系统调用 1. mmap系统调用 2. 系统调用munmap() 3. 系统调用msync() 二. 系统调用mmap()用于共享内存的两种方式&#xff1a; 三. mmap进行内存映射的原理 一. mmap系统调用 1. mmap系统调用 mmap将一个文件或者其它对象映射进内存。文件被映射到多…

Linux内核黑科技——mmap实现详解

前言&#xff1a;故事的开始是这样的&#xff0c;某天在脉脉上看到有人发了下面的帖子&#xff1a; 想不到 mmap 都成了黑科技了&#xff0c;为了让大家都能了解这个黑科技&#xff0c;所以还是写篇文章来详细介绍一下 mmap 的实现吧。 其实&#xff0c;源码分析是比较难写的&…

【Linux】Linux编程之 mmap解析

前言 虚拟内存系统通过将虚拟内存分割为称作虚拟页(Virtual Page&#xff0c;VP)大小固定的块&#xff0c;一般情况下&#xff0c;每个虚拟页的大小默认是4096字节。同样的&#xff0c;物理内存也被分割为物理页(Physical Page&#xff0c;PP)&#xff0c;也为4096字节。 一、…

讲一讲什么是 MMAP

1. mmap 基础概念 mmap 即 memory map&#xff0c;也就是内存映射。 mmap 是一种内存映射文件的方法&#xff0c;即将一个文件或者其它对象映射到进程的地址空间&#xff0c;实现文件磁盘地址和进程虚拟地址空间中一段虚拟地址的一一对映关系。实现这样的映射关系后&#xff…

人工神经网络的应用有哪些方面,人工神经网络在生活中的应用

人工神经网络的应用 人工神经网络&#xff08;Artificial Neural Network&#xff0c;简称ANN &#xff09;&#xff0c;以数学模型模拟神经元活动&#xff0c;是基于模仿大脑神经网络结构和功能而建立的一种信息处理系统。人工神经网络具有自学习、自组织、自适应以及很强的非…

人工神经网络有哪些算法,神经网络都有哪些算法

人工神经网络分类方法 从20世纪80年代末期&#xff0c;人工神经网络方法开始应用于遥感图像的自动分类。 目前&#xff0c;在遥感图像的自动分类方面&#xff0c;应用和研究比较多的人工神经网络方法主要有以下几种&#xff1a;&#xff08;1&#xff09;BP&#xff08;BackP…

深度学习-人工神经网络概述

人工神经网络 简述 很多术语听起来很唬人&#xff0c;“人工神经网络”就属于其中之一。在很多人看来&#xff0c;我们对人类的神经系统还没有研究透彻&#xff0c;这就来了一个“人工的”神经网络&#xff0c;人脑这样复杂&#xff0c;那么人工神经网络一定相当高深莫测。如果…

人工神经网络的应用实例,人工神经网络实际应用

神经网络算法实例说明有哪些&#xff1f; 在网络模型与算法研究的基础上&#xff0c;利用人工神经网络组成实际的应用系统&#xff0c;例如&#xff0c;完成某种信号处理或模式识别的功能、构作专家系统、制成机器人、复杂系统控制等等。 纵观当代新兴科学技术的发展历史&…

人工神经网络算法实战教程

神经网络&#xff08;Artificial Neural Network&#xff0c;也称为人工神经网络&#xff0c;简称ANN&#xff09;具有通过示例学习能力。ANN是受生物神经元系统启发的的信息处理模型&#xff0c;它由大量高度互联的处理元素组成&#xff0c;这些处理元素被称神经元&#xff0c…

人工神经网络的三个要素,神经网络三要素是指

一个完整的人工神经网络包括 人工神经网络主要架构是由神经元、层和网络三个部分组成。整个人工神经网络包含一系列基本的神经元、通过权重相互连接。神经元是人工神经网络最基本的单元。 单元以层的方式组&#xff0c;每一层的每个神经元和前一层、后-层的神经元连接&#x…