内存映射
/* 内存映射: 是将磁盘文件数据映射到内存,用户通过修改内存就能修改磁盘文件 #include <sys/mman.h> void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset); 功能:将一个文件或设备的数据映射到内存中 参数: addr:NULL,由内核决定 length:要映射的数据的长度,值不能为0,建议使用文件的长度 获取文件的长度:stat lseek 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:不同步,写时复制 fd: 需要映射文件的文件描述符 通过open得到 注意:文件大小不能为0,open权限不能于prot参数有冲突,open >= prot offset: 偏移量,一般不用,必须指定的是4k的整数倍,0表示不偏移 返回值: 成功:返回创建的内存首地址 失败:返回MAP_FAILED,(void *) -1 int munmap(void *addr, size_t length); 功能:释放内存映射 参数: addr:要释放的内存的首地址 length:要释放的内存大小,要和mmap函数中的length值相同 */ /* 使用内存映射实现进程间通信: 1、有关系的进程(父子进程) 还没有子进程的时候 通过唯一的父进程,先创建内存映射区 有了内存映射区以后,创建子进程 父子进程共享创建的内存映射区 2、没有关系的进程间通信 准备一个大小不是0的磁盘文件 进程1 通过磁盘文件创建内存映射区 得到一个操作这块内存的指针 进程2 通过磁盘文件创建内存映射区 得到一个操作这块内存的指针 使用内存映射区通信 注意:内存映射区通信,是非堵塞的 */ #include <sys/mman.h> #include <stdio.h> #include <string.h> #include <sys/types.h> #include <unistd.h> #include <sys/stat.h> #include <fcntl.h> #include <stdlib.h> int main() { int fd = open("test.txt", O_RDWR | O_CREAT, 0777); int size = lseek(fd, 0, SEEK_END); // 默认 文件大小 与打开文件的权限相同 同步或非同步 默认 默认 void *shared_addr = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); if(shared_addr == MAP_FAILED) { perror("mmap error"); exit(-1); } int fork_flag = fork(); if(fork_flag == 0) { strcpy((char *)shared_addr, "Hello World"); } else { sleep(1); char str[1024] = {0}; strcpy(str, (char *)shared_addr); printf("recve a info: %s\n", str); } munmap(shared_addr, size); close(fd); return 0; }
# 内存映射实现文件拷贝
/*
使用内存映射实现文件拷贝
1、对原始文件进行内存映射
2、创建一个新文件(拓展该文件)
int truncate(const char *path, off_t length);
off_t lseek(int fd, off_t offset, int whence);
拓展完 写一下 writ(fd, " ", 1);
3、把新文件的数据映射到内存中
4、通过内存拷贝将第一个文件的内存数据拷贝到新的文件内存中
memcpy()
5、释放资源
*/
# 匿名映射
/*
匿名映射
没有文件实体,用于存在关系的进程之间
prot追加MAP_ANONYMOUS
文件描述符-1即可
*/
#include <sys/mman.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <fcntl.h>
#include <string.h>
#include <sys/wait.h>
int main()
{
int len = 4096;
void *shared_addr = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0);
if(shared_addr == MAP_FAILED)
{
perror("mmap error");
exit(-1);
}
int fork_flag = fork();
if(fork_flag == 0)
{
strcpy((char *)shared_addr, "HELLO WORLD");
}
else
{
sleep(1);
printf("%s\n", (char *)shared_addr);
wait(NULL);
}
munmap(shared_addr, len);
return 0;
}
自己选择的路,跪着也要走完。朋友们,虽然这个世界日益浮躁起来,只要能够为了当时纯粹的梦想和感动坚持努力下去,不管其它人怎么样,我们也能够保持自己的本色走下去。