存储映射--mmap

存储映射 使一个磁盘文件与存储空间中的一个缓冲区相映射。 当从缓冲区中取数据,就相当于读文件中的相应字节。 将数据存入缓冲区,则相应的字节就自动写入文件。 使用这种方法,首先应通知内核,将一个指定文件映射到存储区域中。这个映射工作可以通过mmap函数来实现。不通过IO。直接操作内存,效率更高。 mmap函数 函数原型 #include void *mmap(void *addr, size_t length, int prot, int flags,int fd, off_t offset); 参数分析 addr : 建立映射区的首地址,由Linux内核指定。使用时,直接传递NULL。 length : 映射长度。 prot: 映射区权限。 PROT_READ:只读。 PROT_WRITE:只写。 PROT_READ | PROT_WRITE:可读可写。 其它参数不常用,参照手册。 flags: 标志位参数(常用于设定更新物理区域、设置共享、创建匿名映射区). MAP_SHARED:会将映射区所做的操作反映到物理设备(磁盘)上。 MAP_PRIVATE: 映射区所做的修改不会反映到物理设备。 MAP_ANON:匿名映射,不需要已存在的文件进行映射。fd传-1,只能用于亲缘进程间。 fd: 用来建立映射区的文件描述符。 offset: 起点的偏移量,必须是4K的整数倍。因为映射至少一页,比如5000字节的文件,映射内存也是2页大小,不会正好是5000. Note 使用MAP_SHARED的时候,要注意打开文件的权限>=映射区权限。因为如果文件没有写权限,映射区有写权限,那么映射区是无法写入文件的,这和MAP_SHARED的目的相反。如是MAP_PRIVATE就没有此要求。 另外,文件打开权限起码要是可读的,如果不可读,那么怎么读取数据映射到内存呢? 返回值 成功调用返回映射的地址。 失败时返回MAP_FAILED,即void * (-1)。设置errno. munmap函数 函数原型: #include int munmap(void *addr, size_t length); 此函数较为简单,释放映射区,首地址为addr,长度为length. 成功的时候返回0. 失败返回-1且置errno。 应用实例 实现进程间的通信,写进程将一份文件映射到内存,并且每秒写入(覆盖写入)不同的字符串,读进程一直去读。 写进程: struct Person{ char name[30]; int num; }; int main(int argc, char const* argv[]) { //打开文件,作为映射 int fd = open("memTest2.txt", O_RDWR); //int fd = open("memTest2.txt", O_RDWR); int length = sizeof(struct Person); ftruncate(fd, length); printf("fd=%d\n", fd); //映射 struct Person* mem = (struct Person*)mmap(0, length, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); if (mem == MAP_FAILED) { perror("mmap err"); return -1; } printf("映射区地址:%0x\n", mem); int num = 1; while (1) { mem->num = num++; sprintf(mem->name, "I am a Person%03d", mem->num); sleep(1); } //释放 munmap(mem, length); close(fd); return 0; } 读进程: struct Person{ char name[30]; int num; }; int main(int argc, char const* argv[]) { //打开文件,作为映射 int fd = open("memTest2.txt", O_RDWR); int length = sizeof(struct Person); printf("fd=%d\n", fd); //映射 struct Person* mem = (struct Person *)mmap(0, length, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); if(mem == MAP_FAILED) { perror("mmap err"); return -1; } printf("映射区地址:%0x\n", mem); while (1) { printf("name=%s,num=%d\n", mem->name,mem->num); sleep(1); } //释放 munmap(mem, length); close(fd); return 0; }https://www.cnblogs.com/love-jelly-pig/p/10063442.html
50000+
5万行代码练就真实本领
17年
创办于2008年老牌培训机构
1000+
合作企业
98%
就业率

联系我们

电话咨询

0532-85025005

扫码添加微信