当前位置:网站首页>共享内存-内存映射-共享文件对象
共享内存-内存映射-共享文件对象
2022-07-30 02:18:00 【猿饵块】
什么是映射
动态连接库怎么实现的?
什么是写时复制?
内存映射怎么实现
mmap,munmap:
mmap将一个文件或者其它对象的数据映射到指定的内存。(通俗一点就是从其他地方指定的位置拷贝数据到本进程指定长度的地址当中)
mmap操作提供了一种机制,让用户程序直接访问设备内存,这种机制,相比较在用户空间和内核空间互相拷贝数据,效率更高。在要求高性能的应用中比较常用。
munmap执行相反的操作,删除特定内存区的对象映射。
#include <sys/mman.h>
void *mmap(void *start, size_t length, int prot, int flags, int fd, off_t offset);
int munmap(void *start, size_t length);
start:映射区内存的起始地址,设置为0时表示由系统决定映射区的起始地址。
length:映射区内存的长度。注意,这个不是映射的数据长度。
为什么length=1,也可以映射正文件的内容:
prot:内存区保护标志,不能与文件的打开模式冲突。是以下的某个值,可以通过or运算(“|”)合理地组合在一起
PROT_EXEC //内存区内容可以被执行
PROT_READ //内存区内容可以被读取
PROT_WRITE //内存区可以被写入
PROT_NONE //内存区不可访问
flags:设置内存区的属性,MAP_SHARED----共享的,写入的内容可以写入文件,MAP_PRIVATE--本进程私有,写入的内容最终不会保存在文件中。
fd:文件描述符。
offset:被映射对象内容起始点。
注意:mmap返回的地址类型是void*,需要强转。
mmap失败返回MAP_FAILED(-1)
memcpy:
memory copy内存(数据)拷贝函数
void *memcpy(void *dest, const void *src, size_t n);
它的功能是从src的开始位置拷贝n个字节的数据到dest。如果dest存在数据,将会被覆盖。memcpy函数的返回值是dest的指针。memcpy函数定义在string.h头文件里。
void main()
{
char arr[10]="aaaaaaaa";
char* str="uiefcb";
memcpy(arr,str,6);
printf("%s\n",arr);
}
输出:uiefcbaa
mmap的实现
#include <iostream>
#include <sys/types.h>
#include <unistd.h>
#include <sys/shm.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <assert.h>
#include <cstring>
using namespace std;
char* shm_ptr=nullptr;
int fd=-1;
int main(){
//1,打开要关联的文件,获得文件描述符
fd=open("shareFile.c",O_CREAT|O_RDWR,0666);
assert(fd!=-1);
//2,设置文件大小
int ret=ftruncate(fd,10);
assert(ret!=-1);
//3,文件映射,获取物理内存,返回内存首地址,返回的就是一个指针
shm_ptr=(char*)mmap(NULL,10,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);
assert(shm_ptr!=MAP_FAILED);
//4,用指针向内存写入数据,内存中的数据会被保存到文件中
strcpy(shm_ptr,"success");
//5,关闭
close(fd);
munmap(shm_ptr,10);
return 0;
}共享内存实现进程间共享文件对象--posix
#include <iostream>
#include <sys/types.h>
#include <unistd.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <assert.h>
/*
*共享内存建立之后,进程想要使用,还要将共享内存和自己的虚拟地址建立关联
*申请--关
*
* */
using namespace std;
char* shm_ptr=nullptr;
int shm_fd=-1;
int main(){
//1,注意:指定的共享文件对象一定要以/开头,不同于open,这里不指定路径,因为这个共享文件
//对象只是暂时的使用,使用完之后如果文件本来存在,shm_unlink会清除共享时修改的内容,还原文件
//本来的数据,如果文件是被创建的,文件会被删除。
shm_fd=shm_open("/shareFile.c",O_CREAT|O_RDWR,0666);
assert(shm_fd!=-1);
//2,指定共享文件对象的大小
int ret=ftruncate(shm_fd,1024);
assert(ret!=-1);
//3,申请物理内存,将物理内存和共享文件对象相互关联,返回物理内存首地址
shm_ptr=(char*)mmap(NULL,1024,PROT_READ|PROT_WRITE,MAP_SHARED,shm_fd,0);
assert(shm_ptr!=MAP_FAILED);
pid_t pid=fork();
if(pid==0){
for(int i=0;i<10;++i)
cin>>shm_ptr[i];
sleep(10);
}
else if(pid>0){
sleep(20);
cout<<shm_ptr<<endl;
munmap(shm_ptr,1024);
shm_unlink("./shareFile.c");
}else return -1;
return 0;
}
注意:编译需要链接 -lrt
共享内存实现进程间共享文件对象2
//进程1--写数据
#include <iostream>
#include <sys/types.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <assert.h>
#include <cstring>
using namespace std;
int main(){
//1,ftok(把一个已存在的路径名和一个整数标识符转换成IPC键值),注意返回的key不是指定数值,随
//机的
key_t key=ftok("./shareFile.c",1024);
assert(key!=-1);
cout<<key<<endl;
//2,创建或者获取共享内存,返回共享内存标识符
int shmid=shmget(key,1024,IPC_CREAT|0777);
//3,关联当前进程的虚拟地址空间--shmat,使用完后要用shmdt分离虚拟地址空间和物理内存
void* shm=shmat(shmid,NULL,0);
char* shm_ptr=(char*)shm;
memset(shm_ptr,0,1024);
for(int i=0;i<10;++i)
cin>>shm_ptr[i];
//4,使用完毕,解出映射
shmdt(shm_ptr);
return 0;
}
//进程2--读数据
#include <iostream>
#include <sys/types.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <assert.h>
#include <cstring>
using namespace std;
int main(){
//1,ftok(把一个已存在的路径名和一个整数标识符转换成IPC键值)
key_t key=ftok("./shareFile.c",1024);
assert(key!=-1);
cout<<key<<endl;
//2,创建或者获取共享内存,返回共享内存标识符
int shmid=shmget(key,1024,IPC_CREAT|0777);
//3,关联当前进程的虚拟地址空间--shmat,使用完后要用shmdt分离虚拟地址空间和物理内存
void* shm=shmat(shmid,NULL,0);
char* shm_ptr=(char*)shm;
cout<<shm_ptr<<endl;
//4,使用完毕,解出映射
shmdt(shm_ptr);
return 0;
}
边栏推荐
猜你喜欢

Houdini 地形知识点
![[VMWARE--Shared files]](/img/34/1f1609edc82c0a134886f9bf936f7f.png)
[VMWARE--Shared files]
Linux Jenkins查找缓存文件及删除 (2022-07测试可用)

短期风电预测(Matlab代码实现)

STM32L4R9ZIY6PTR STM32L4 high-performance embedded-MCU

【2023海康威视提前批笔试题】~ 题目及参考答案

uni-app如何配置APP自定义顶部标题栏

CVPR 2022 Best Paper -- Learning to Solve Hard Minimal Problems

超详细的MySQL基本操作

Is it difficult for AI to land?Cloud native helps enterprises quickly apply machine learning MLOps
随机推荐
English grammar_indefinite pronouns -some & any
Is it difficult for AI to land?Cloud native helps enterprises quickly apply machine learning MLOps
JS开发3D建模软件
错误:“filesystem“ 不是 “std“ 的成员
力扣刷题训练(二)
What to test for app testing
binary search tree
mysql 报错 is too long for user name (should be no longer than 16)
ufw set firewall rules
信息系统项目管理师核心考点(五十四)配置项分类、状态与版本
Type-C charging and OTG chip - LDR6028A
【MySQL】SQL学习
实现导入市场活动:
把@Transactional事务注解用到如此炉火纯青,真的强!
go grpc 自定义拦截器
有一个设计时钟的题目,进行详细分析(三)
关于 SAP Fiori 应用的离线使用
Performance Testing Theory 1 | Sorting out difficult problems in performance testing
绘制概率密度图
EL 表达式