当前位置:首页 > 内存 > 正文

windows共享内存实现原理(电脑什么也没开内存占一半)

  • 内存
  • 2024-06-04 04:57:47
  • 8849

一、windows下利用文件映射实现共享内存Windows下使用文件映射实现共享内存的方法比较简单。以下是实现代码,详细内容在注释中说明。
类似于linux下shm的调用操作。这个类还没有经过太多测试。欢迎提出问题和错误~~:)
#includewindows.h#includestring#includeiostream#std::string;usingstd::cout;usingstd::endl;#pragmawarning(disable:4311)classshareMemory{private:LPWSTRshm_name_u;boolis_create_file;void*sh_base;HANDLEsemaphore;HANDLEfile_mapping;intaddr_len;public:/*create_file用来指定是否使用页面文件映射磁盘是使用文件映射,共享内存后不会造成非法访问问题内存释放,但会在磁盘上创建一个文件,文件名由shm_name参数给出。如果使用页面文件映射,则不会在磁盘上创建文件*/shareMemory(conststringshm_name,boolcreate_file=false):is_create_file(create_file){constchar*_c_shm_name=shm_name.c_str();()+1;shm_name_u=(LPWSTR)malloc(_size*2)=始终无效,file_attribute_normal,0);#ifdef_DEBUGif(_file_handle==INVALID_HANDLE_VALUE)cout"cannotcreatefile!weusepagefileinstead!";#endif//end_DEBUG}/*打开指定名称的文件映射,如果不存在则创建一个*/file_mapping=Open_READITE(PAGE,假,shm_name_u);if(file_mapping!=NULL)gotofile_mapping_exist;CreateFileMapping(_file_handle,NULL,PAGE_READWRITE,0,length,shm_name_u);#ifdef_DEBUG断言(file_mapping=nULL);file_mapping_exist:sh_base=MapViewOfFileEx(file_mapping,protect,0,0,length,addr);*dest,void*src,intsize){if(!check_adress(dest))return-1;/*使用信号量进行保护;映射区域(只有同一进程中不同线程调用时才进行保护)*/WaitForSingleObject(semafor,INFINITE(dest,src,_write_count););return_write_count;}/*从共享内存中读取数据,并返回读取的数据字节数**/intshm_read(void*src,void*dest,intsize){if(!check_adress(src))return-1;=(int)sh_base+addr_len-(int)src;if(_read_countsize)_read_count=size;memcpy(dest,src,_read_count);return_read_count;}~shareMemory(){UnmapViewOfFile(sh_basefree(shm_name_u);信号量);CloseHandle(file_mapping);}private:/*执行地址检测*/boolcheck_adress(void*addr){if((int)addr(int)sh_base)||(int)addr(int)sh_base+addr_len)){SetLastError(ERROR_ACCESS_DENIED);#ifdef_DEBUGprintf("accessdenied,thedestinationaddressoutofthemapview!");#endif//_DEBUGreturnfalse;}returntrue;}};
测试:
编写process的主要函数:
intmain(){shareMemorysm("boost",false);void*bs=_open(NULL,1000*4,FILE_MAP_WRITE);if(bs==NULL)return-1;inta[10];for(inti=0;i10;++i)a[i]=i;_write(bs,a,10*4);Sleep(100000);}
读取过程主要函数:
intmain(){shareMemorysm("boost",false);void*bs=_open(NULL,1000,FILE_MAP_READ);if(bs==NULL){cout"null";return-1;}intb[10];_read(bs,b,10*4);for(inti=0;i10;++i)coutb[i]"";}


二、有独立显卡怎么还共享内存容量

系统内存共享是指将部分内存作为显存,集成显卡和独立显卡都可以共享系统内存。独立显卡共享内存容量的方法如下:

1重新启动计算机,按住键盘上的“Del”键进入主板BIOS。进入主板BIOS后,左键点击上方的“高级模式”即可切换到BIOS设置的高级模式。

2.切换到“高级模式”后,点击界面左侧的“设置”,然后点击“高级”。可以看到“共享内存视频内存”的容量。从32MB到1GB中选择单击仅选择一个。

3修改完成后,按键盘上的F10保存修改后的BIOS设置,退出BIOS并自动重启,进入Windows桌面后,共享显存设置将被修改。

4.共享系统内存对玩游戏影响很大由于集成显卡不好,会影响Win7的视觉效果,所以共享内存技术大多用在集成显卡的主板上。

5.显存共享技术多用于带有集成显卡的主板上,也用于独立显卡固态显存较少的情况。为了节省硬件成本,集成显卡不再需要固态显存,直接使用内存,因为显存是共享内存技术。

6只有TC开启时才会共享,而不是显存不足时才共享。当然,TC可以根据情况开启和关闭。显存不足需要共享显存容量这多见于早期的小显存显卡为了省钱,就采用了小显存。


三、共享内存原理

Linux2.2.x内核支持多种共享内存方法,例如mmap()系统调用、Posix共享内存和SystemV共享内存。

共享内存可以说是进程间通信最有用的方法,也是最快的IPC形式。两个不同的进程A和B共享内存,这意味着相同的物理内存被分配给进程A和B各自的进程地址空间。进程A可以立即看到进程B对共享内存中数据的更新,反之亦然。由于多个进程共享同一内存区域,因此需要某种同步机制,例如互斥锁和信号量。

SystemV共享内存原理

进程间需要共享的数据放在一个叫做IPC共享内存区域的地方。所有需要访问共享区域的进程都必须将共享区域分配给本进程的地址空间。SystemV共享内存通过shmget检索或创建IPC共享内存区域并返回相应的标识符。内核确保shmget获取或创建共享内存区域,并初始化共享内存区域对应的shmid_kernel结构。同时,它还会在特殊文件系统shm中创建并打开一个同名文件,并在内存和inode结构中建立该文件对应的文件,新打开的文件不属于任何进程(任何进程都可以访问共享内存区域)。这一切都是由shmget系统调用完成的。

Linux有一个系统调用,叫做mmap(),这个mmap()可以将一个文件映射到进程的地址空间(进程使用的虚拟内存),以便进程可以读写。进程地址空间来读取和写入该文件。

你可能会觉得很奇怪,我明明是在写入内存,为什么还要写入文件呢?他们是如何转变的?

是的,你写的其实是存,但是你写的内存不是普通的内存。你写入这块内存的内容会在一段时间后被内核写入到这个文件中。写文件实际上最终是将数据写入设备(硬盘、NandFlash等)。

mmap的主要优点是为用户程序随机访问、操作文件提供了一种便捷的操作方法,另外对于超大文件(无法一次读入内存)提供了高效的操作方法。方法。

内核中有一个特殊的文件系统。这个文件系统的存储介质就是RAM。

在shmget()调用之后,系统会为您在该文件系统上创建一个文件,但这一次它只是创建该文件。

然后你应该调用shmat(),内核将使用mmap将文件映射到进程地址空间。此时就可以对分配的地址进行读写操作了。。

一段时间后,内核会将您输入的内容写入文件中。但是这个文件的存储介质是内存,那么它会做什么呢?你明白吗?

答:会写入内存

首先我们看一下如果不使用内存映射文件的情况下的处理流程。首先我们需要将磁盘文件的内容读入内存,然后修改,最后写回磁盘。读取磁盘文件的第一步是通过系统调用。它首先将文件内容从磁盘复制到内核空间的缓冲区,然后将数据复制到用户空间副本。第三步回写也需要两份数据。

所以我们基本上会有四份数据副本,因为大文件的数据量非常大,几十GB甚至更大,所以复制的成本非常高。

内存映射文件是操作系统提供的一种机制,可以减少不必要的数据拷贝,从而提高效率。它将文件直接映射到用户空间,并使用mmap()在页错误处理期间不复制数据。由于mmap()将文件直接映射到用户空间,因此函数根据这种映射关系将文件直接从硬盘复制到用户空间。因此,只进行一次数据拷贝,读取时效果是两次数据拷贝的两倍。因此,内存映射的效率高于读/写的效率。

一般来说,读操作可以满足大多数文件操作的要求,但对于一些需要数十GB甚至更大存储空间的特殊应用领域,则采用这种常见的文件处理方式。不工作。

mmap将文件或其他对象映射到内存。文件被分配到多个页面如果文件大小不是所有页面大小的总和,则最后一页上未使用的空间将被清空。munmap执行相反的操作,删除特定地址范围的对象映射。

使用mmap将文件映射到进程后,就可以直接使用这个虚拟地址来读写文件,而不必调用读写直接访问这个段的系统调用进行写入时内存,不会写入超过当前文件大小的内容。

参考地址: