mmap存储映射IO

mmap,munmap——

#include <sys/mman.h>

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

mmap, munmap - map or unmap files or devices into memory.

存储映射IO使一个磁盘文件与存储空间中的一个缓冲区相映射。于是当从缓冲区取数据,就相当于读文件中的相应字节。与此类似,将数据存入缓冲区,则相应字节就自动地写入文件。这样就可以在不使用read和write的情况下执行IO。为了使用这种功能,应首先告诉内核将一个给定的文件映射到一个存储区域中,这是由mmap函数实现的。

addr参数用于指定映射存储区的起始地址,通常将其设置为0,这表示由系统选择该映射区的起始地址,此函数的返回地址是该映射区的起始地址。

fd指定要被映射文件的描述符,在映射该文件到一个地址空间之前,先要打开该文件。

length是映射的字节数。

offset是要映射字节在文件中的起始偏移量。

prot参数说明对映射存储区的保护要求,但不能超过文件open模式访问权限,prot可选值如下:

PROT_EXEC Pages may be executed.

PROT_READ Pages may be read.

PROT_WRITE Pages may be written.

PROT_NONE Pages may not be accessed.

flags参数影响映射存储区的多种属性,其中MAP_SHARED和MAP_PRIVATE两者必须选择其一,还有许多其它的MAP_XXX是可选的。

mprotect函数可以更改一个现有映射存储区的权限,msync函数类似于fsync,作用于存储映射区,将该页冲洗到被映射的文件中。

SIGSEGV和SIGBUS是两个与映射存储相关的两个信号。前者通常用于指示进程试图访问对它不可用的存储区,如只读的映射存储区,后者指示访问映射区不存在的部分。

调用fork后,子进程继承映射存储区,但exec后的新程序则不继承。

下面是一个用存储映射IO复制文件的例子,与read/write相比,不同操作系统下的用户和系统CPU时间可能不同,但时钟时间明显是存储映射IO要比read/write快一点。因为:用read和write时,要先将数据从内核缓冲区复制read到应用程序缓冲区,然后又将应用程序缓冲区中的数据复制write到内核缓冲区;而用mmap和munmap时,则直接将映射到应用程序地址空间的一个内核缓冲区中的数据复制到另一个同样映射到应用程序地址空间中的内核缓冲区中。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <sys/mman.h>

int main(int argc, char *argv[])
{
    int fdin;
    int fdout;
    void *src;
    void *dst;
    struct stat statbuf;

    if (3 != argc) {
        printf("usage: %s <fromfile> <tofile>\n", argv[0]);
        return -1;
    }

    if ((fdin = open(argv[1], O_RDONLY)) < 0) {
        printf("can‘t create %s for reading\n", argv[1]);
        return -1;
    }

    if ((fdout = open(argv[2], O_RDWR | O_CREAT | O_TRUNC)) < 0) {
        printf("can‘t create %s for writing\n", argv[2]);
        return -1;
    }

    if (fstat(fdin, &statbuf) < 0) {
        printf("fstat error\n");
        return -1;
    }

    if (lseek(fdout, statbuf.st_size - 1, SEEK_SET) == -1) {
        printf("lseek error\n");
        return -1;
    }

    if (write(fdout, "", 1) != 1) {
        printf("write error\n");
        return -1;
    }

    if ((src = mmap(0, statbuf.st_size, PROT_READ, MAP_SHARED, fdin, 0)) == MAP_FAILED) {
        printf("mmap error for input\n");
        return -1;
    }

    if ((dst = mmap(0, statbuf.st_size, PROT_READ | PROT_WRITE, MAP_SHARED, fdout, 0)) == MAP_FAILED) {
        printf("mmap error for output\n");
        return -1;
    }

    memcpy(dst, src, statbuf.st_size);

    exit(0);
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-12 16:44:11

mmap存储映射IO的相关文章

存储映射IO

3.6.7.1.mmap函数3.6.7.2.LCD显示和IPC之共享内存3.6.7.3.存储映射IO的特点(1)共享而不是复制,减少内存操作(2)处理大文件时效率高,小文件不划算 总结:存储映射IO其实本质上就是共享内存,和进程间通信的IPC共享内存是一样的,区 别在于: 存储映射IO:是访问设备文件的说法,例如访问LCD设备,我们的进程是一个视频播放器 ,那么他需要将硬盘中的视频数据读取到内存中,然后再把内存中的数据拷贝到LCD驱动 维护的显存中去,之后硬件会自动实现视频的显示:这个是一般的流

文件映射IO(mmap-mprotect-msync-munmap)函数

本文介绍在POSIX环境使用文件映射IO操作的方法,文件映射IO又被称为存储映射IO,对于普通文件而言,很多时候它是高效的,它实际减少了数据的复制:同时它也可以用于特殊的地方,用于进程之间的通信,共享内存的一种方式. 我们能够把一个文件想象成一块连续的数据,从纯粹的数据角度来看,任何普通文件都可以这么理解.文件映射实际上是把文件的这块数据与我们程序里的一块内存对应上了,使用我们操作这块内存的时候,看上去实际在操作这个文件.这就是文件映射的概念.这个概念很伟大,它直接避免了内核与用户之间的一层数据

存储映射--mmap

存储映射 使一个磁盘文件与存储空间中的一个缓冲区相映射. 当从缓冲区中取数据,就相当于读文件中的相应字节. 将数据存入缓冲区,则相应的字节就自动写入文件. 使用这种方法,首先应通知内核,将一个指定文件映射到存储区域中.这个映射工作可以通过mmap函数来实现.不通过IO.直接操作内存,效率更高. mmap函数 函数原型 #include <sys/mman.h> void *mmap(void *addr, size_t length, int prot, int flags,int fd, o

八、文件IO——存储映射

8.1 存储映射介绍 8.1.1 概念 存储映射是一个磁盘文件与存储空间的一个缓存相映射,对缓存数据的读写就相应的完成了文件的读写. 文件操作部分映射到虚拟内存的一块区域,我们对虚拟内存映射的那块区域进行读写操作,读写之后,那块区域自动同步到文件当中. 4G空间分布: 共享内存映射区就是文件映射到的内存区. 8.1.2 mmap---建立内存映射 1 #include <unistd.h> 2 #include <sys/mman.h> 3 //mmap(建立内存映射) 4 voi

Linux的mmap内存映射机制解析

在讲述文件映射的概念时,不可避免的要牵涉到虚存(SVR 4的VM).实际上,文件映射是虚存的中心概念, 文件映射一方面给用户提供了一组措施,好似用户将文件映射到自己地址空间的某个部分,使用简单的内存访问指令读写文件:另一方面,它也可以用于内核的基本组织模式,在这种模式种,内核将整个地址空间视为诸如文件之类的一组不同对象的映射.中的传统文件访问方式是,首先用open系统调用打开文件,然后使用read, write以及lseek等调用进行顺序或者随即的I/O.这种方式是非常低效的,每一次I/O操作都

第3章 文件I/O(7)_高级文件操作:存储映射

8. 高级文件操作:存储映射 (1)概念: 存储映射是一个磁盘文件与存储空间的一个缓存相映射,对缓存数据的读写就相应的完成了文件的读写. (2)mmap和munmap函数 头文件 #include<sys/types.h> #include<sys/mman.h> 函数 void* mmap(void* addr, size_t length, int prot, int flags,                       int fd, off_t offset); int

【Linux编程】存储映射I/O

存储映射I/O使一个磁盘文件与存储空间中的一个缓冲区相映射,对缓冲区的读.写操作就是对文件的读.写操作,从而可以不再使用read.write系统调用. 将文件映射到存储区的函数由mmap完成,函数原型如下: #include <sys/mman.h> /* 成功返回映射区起始地址,出错返回MAP_FAILED */ void *mmap(void *addr, size_t len, int prot, int flag, int filedes, off_t off); 参数说明: addr

共享内存之——mmap内存映射

共享内存允许两个或多个进程共享一给定的存储区,因为数据不需要来回复制,所以是最快的一种进程间通信机制.共享内存可以通过mmap()映射普通文件 (特殊情况下还可以采用匿名映射)机制实现,也可以通过systemV共享内存机制实现.应用接口和原理很简单,内部机制复杂.为了实现更安全通信,往往还与信号灯等同步机制共同使用. 这一篇详解mmap内存文件映射原理及其案例,system V共享内存 以及他们的区别将在后面的随笔中讨论. 非原创,内容源于互联网 mmap内存文件映射 一.传统文件访问 unix

Python之mmap内存映射模块(大文本处理)说明

背景: 通常在UNIX下面处理文本文件的方法是sed.awk等shell命令,对于处理大文件受CPU,IO等因素影响,对服务器也有一定的压力.关于sed的说明可以看了解sed的工作原理,本文将介绍通过python的mmap模块来实现对大文件的处理,来对比看他们的差异. 说明: mmap是一种虚拟内存映射文件的方法,即将一个文件或者其它对象映射到进程的地址空间,实现文件磁盘地址和进程虚拟地址空间中一段虚拟地址的一一对映关系.关于系统中mmap的理论说明可以看百度百科和维基百科说明以及mmap函数介