存储映射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:指定映射存储区的起始地址,通常为0表示由系统选择起始地址。
  • len:须要映射的字节数。
  • prot:对映射存储区的保护要求,不能超过open文件时的权限。
    • PROT_READ:映射区可读
    • PROT_WRITE:映射区可写
    • PROT_EXEC:映射区可运行
    • PROT_NONE:映射区不可訪问
  • flag:影响映射存储区的属性。
    • MAP_FIXED:返回值必须等于addr,不利于移植。不鼓舞使用。
    • MAP_SHARED:表示存储操作相当于对该文件的write。
    • MAP_PRIVATE:对映射区的存储操作导致创建该映射文件的一个私有副本。
  • filedes:指定要被映射的文件描写叙述符,映射之前须要先打开该文件。
  • off:要映射字节在文件里的起始偏移量。通常为0。

存储映射例如以下所看到的:


測试代码:
#include <stdio.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <string.h> #define FILE_MODE (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) int main(int argc, char *argv[])
{
int fdin, fdout;
void *src, *dst;
struct stat statbuf; if (argc != 3)
{
printf("usage: %s <fromfile> <tofile>\n", argv[0]);
return -1;
} fdin = open(argv[1], O_RDONLY);
fdout = open(argv[2], O_RDWR | O_CREAT | O_TRUNC, FILE_MODE); fstat(fdin, &statbuf); lseek(fdout, statbuf.st_size - 1, SEEK_SET);
write(fdout, " ", 1); /* lseek偏移量大于文件长度时。写操作将加长文件 */ src = mmap(0, statbuf.st_size, PROT_READ, MAP_SHARED, fdin, 0);
dst = mmap(0, statbuf.st_size, PROT_READ | PROT_WRITE, MAP_SHARED, fdout, 0); memcpy(dst, src, statbuf.st_size); /* 数据复制 */ munmap(src, statbuf.st_size);
munmap(dst, statbuf.st_size); return 0;
}

此函数实现了文件内容之间的拷贝。

lseek + write的组合操作使得目标文件的大小添加到和源文件大小同样。由于当lseek设置的文件偏移量大于文件当前长度时。下一个写操作将会使文件增大。假设没有对目标文件扩大。那么进程会接收到SIGBUS信号。表示存储区中有地址无法映射到文件里。


mmap实际上是将包括文件内容的内核缓冲区映射到应用程序地址空间,然后用memcpy直接进行数据的拷贝。其优势在于避免了类似read、write系统调用,在内核空间和用户空间之间的数据传递。

參考:
《unix环境高级编程》 P390-P395.

【Linux编程】存储映射I/O的更多相关文章

  1. UNIX环境高级编程——存储映射I/O(mmap函数)

         共享内存可以说是最有用的进程间通信方式,也是最快的IPC形式,因为进程可以直接读写内存,而不需要任何数据的拷贝.对于像管道和消息队列等通信方式,则需要在内核和用户空间进行四次的数据拷贝,而共 ...

  2. Linux编程---I/O部分

    非常多函数都能够在网上找到,也比較基础,所以原型仅仅给出了函数名.详细用到再man吧. 输入输出是个非常重要的一块内容.差点儿网络相关的东西基本都是靠底层IO调用来实现的. 好吧.还是先踏踏实实的介绍 ...

  3. Linux 编程学习笔记----过程管理和项目发展(在)

    转载请注明出处,http://blog.csdn.net/suool/article/details/38406211,谢谢. Linux进程存储结构和进程结构 可运行文件结构 例如以下图: 能够看出 ...

  4. 牛人整理分享的面试知识:操作系统、计算机网络、设计模式、Linux编程,数据结构总结 转载

    基础篇:操作系统.计算机网络.设计模式 一:操作系统 1. 进程的有哪几种状态,状态转换图,及导致转换的事件. 2. 进程与线程的区别. 3. 进程通信的几种方式. 4. 线程同步几种方式.(一定要会 ...

  5. 【转】牛人整理分享的面试知识:操作系统、计算机网络、设计模式、Linux编程,数据结构总结

    基础篇:操作系统.计算机网络.设计模式 一:操作系统 1. 进程的有哪几种状态,状态转换图,及导致转换的事件. 2. 进程与线程的区别. 3. 进程通信的几种方式. 4. 线程同步几种方式.(一定要会 ...

  6. Linux 编程中的API函数和系统调用的关系【转】

    转自:http://blog.chinaunix.net/uid-25968088-id-3426027.html 原文地址:Linux 编程中的API函数和系统调用的关系 作者:up哥小号 API: ...

  7. linux编程获取本机网络相关参数

    getifaddrs()和struct ifaddrs的使用,获取本机IP 博客分类: Linux C编程   ifaddrs结构体定义如下: struct ifaddrs { struct ifad ...

  8. 高级I/O之存储映射I/O

    存储映射I/O(Memory-mapped I/O)使一个磁盘文件与存储空间中的一个缓冲区相映射.于是当从缓冲区中取数据,就相当于读文件中的相应字节.与此类似,将数据存入缓冲区,则相应字节就自动地写入 ...

  9. 面试知识:操作系统、计算机网络、设计模式、Linux编程,数据结构总结

    基础篇:操作系统.计算机网络.设计模式 一:操作系统 1. 进程的有哪几种状态,状态转换图,及导致转换的事件. 2. 进程与线程的区别. 3. 进程通信的几种方式. 4. 线程同步几种方式.(一定要会 ...

随机推荐

  1. 经典排序算法 - 基数排序Radix sort

    经典排序算法 - 基数排序Radix sort 原理类似桶排序,这里总是须要10个桶,多次使用 首先以个位数的值进行装桶,即个位数为1则放入1号桶,为9则放入9号桶,临时忽视十位数 比如 待排序数组[ ...

  2. Swift - 短信发送功能的实现

    使用MessageUI.framework框架可以实现短信发送功能,步骤如下: (1)首先判断设备是否有发送短信功能 (2)如果设备允许发送短信,创建一个MFMessageComposeViewCon ...

  3. 转:python idle 清屏问题的解决

    http://www.cnblogs.com/maybego/p/3234055.html python idle 清屏问题的解决 在学习和使用python的过程中,少不了要与python idle打 ...

  4. 用Delphi实现Windows的鼠标钩子函数

    Delphi是基于PASCAL语言的Windows编程工具,功能十分强大.然而在Delphi的帮助文件中,对Windows API函数的说明沿袭了 VC 的格式,和VC一样,对很多API函数的用法没有 ...

  5. VPS服务器下的centos网卡配置详解……

    自动激活网卡 安装了CENTOS 6.X后,每次启动了系统都需要手动激话网卡,以下方法可以在系统启动后自动激活网卡. cat /etc/sysconfig/network-scripts/ifcfg- ...

  6. 几十篇GDI以及MFC自绘的文章

    http://www.cnblogs.com/lidabo/category/434801.html

  7. hadoop学习之ZooKeeper

    1. 什么是ZooKeeper? ZooKeeper是一组工具,用来配置和支持分布式调度. 它能处理分布式应用的“部分失败”问题. 什么是部分失败? 部分失败是分布式处理系统的固有特征,即发送者无法知 ...

  8. C++STL之set容器及stream类

    首先讲stream流类 头文件#include <sstream> 其功能是进行不同类型之间的转换,跟C语言 fscanf 和 fprintf 作用是同样的,可是比C语言的更简便更好用. ...

  9. Light OJ 1429 Assassin`s Creed (II) BFS+缩点+最小路径覆盖

    题目来源:Light OJ 1429 Assassin`s Creed (II) 题意:最少几个人走全然图 能够反复走 有向图 思路:假设是DAG图而且每一个点不能反复走 那么就是裸的最小路径覆盖 如 ...

  10. SAP屏幕框架的创建

    1.创建包括文本的基本框架 REPORT ztest_sum. TABLES:mara,syst. WITH FRAME TITLE mytitle. "mytitle是框架上的文本 ) A ...