各平台共享記憶體的實現方式

2021-06-07 22:57:00 字數 3915 閱讀 4134

在記憶體共享問題上,unix歷史上主要有兩個標準:posix與system v,相比來說posix標準更符合統一風格要求,與檔案系統結合,更易於使用。除了這兩個標準,還有一種基於磁碟檔案對映的機制。

posix標準提供一種共享記憶體檔案裝置,通過訪問共享記憶體檔案裝置來實現程序間的資料共享。共享記憶體檔案是通過shm_open建立,通過shm_unlink刪除,這和普通檔案的建立很相似。shm_open包含建立與開啟兩個動作,如果已經存在的話,也是通過shm_open開啟。可以指定一些flag規定shm_open的行為,比如不存在時是否建立,是否排出已存在的例項,以及開啟的讀寫許可權。

#include #include /* for mode constants */

#include /* for o_* constants */

int shm_open(const char *name, int oflag, mode_t mode);

int shm_unlink(const char *name);

剛建立的共享記憶體檔案長度為0,一般需要馬上擴充套件其長度,和普通檔案一樣,通過 ftruncate調整長度。

#include #include int ftruncate(int fd, off_t length);
在共享記憶體不使用的時候,通過close關閉,和普通檔案關閉的介面是同乙個。關閉不會刪除共享記憶體檔案,即使最後乙個開啟被close了也不會刪除,之後還可以再開啟。只有呼叫shm_unlink才會刪除共享記憶體檔案。

#include int close(int fd);
如果要訪問共享資料,需要將共享記憶體檔案對映到程序空間,mmap被用來實現這個對映,而munmap解除相應的對映。mmap還有其他的應用方式,與系統記憶體相關的操作幾乎都離不開mmap和munmap。

#include void *mmap(void *addr, size_t length, int prot, int flags,

int fd, off_t offset);

int munmap(void *addr, size_t length);

system v共享記憶體是system v ipc的成員,沒有與檔案繫結,但是通過ipc命令如ipcs,ipcrm可以操作system v ipc物件。輸入ipcs命令會列印下面的內容:

------ shared memory segments --------

key shmid owner perms bytes nattch status

------ semaphore arrays --------

key semid owner perms nsems

------ message queues --------

key msqid owner perms used-bytes messages

其中shared memory segments就是共享記憶體。

可以看到ipc物件的前四項屬性是所有ipc型別都有的,key是訪問的索引值,開啟時由使用者指定;id是ipc內部分配的編號,在開啟時返回;owner是所有者id;perms是許可權資訊。

在命令列中,可以通過ipcrm命令刪除ipc物件。ipcrm的引數指定刪除那種物件,-m表示共享記憶體(shared memory segments),-s表示訊號量集(semaphore arrays),-q表示訊息佇列(message queues),也可以是大寫的-m、-s、-q,小寫使用內部id查詢,大寫使用key查詢。在ipc物件被刪除後,內部id會變成0,就不能再被開啟了。

開啟和建立system v共享記憶體的介面是shmget,key可以隨便指定,保證唯一且不等於-1就行。

#include #include int shmget(key_t key, size_t size, int shm***);
也可以通過庫函式 ftok 來生成乙個唯一的key。

#include #include key_t ftok(const char *pathname, int proj_id);
ftok使用乙個檔名和乙個唯一id作為引數,這個id雖然是int型別,但是只有8位被使用,所以只能傳乙個位元組,另外標準中規定不能為0。

#include #include void *shmat(int shmid, const void *shmaddr, int shm***);

int shmdt(const void *shmaddr);

#include #include int shmctl(int shmid, int cmd, struct shmid_ds *buf);
#include #include #include int open(const char *pathname, int flags);

int open(const char *pathname, int flags, mode_t mode);

int creat(const char *pathname, mode_t mode);

__in handle hfile,

__in_opt lpsecurity_attributes lpattributes,

__in dword flprotect,

__in dword dwmaximumsizehigh,

__in dword dwmaximumsizelow,

__in_opt lpctstr lpname);

__in dword dwdesiredaccess,

__in bool binherithandle,

__in lpctstr lpname);

bool winapi closehandle(

__in handle hobject

);

lpvoid winapi mapviewoffile(

__in dword dwdesiredaccess,

__in dword dwfileoffsethigh,

__in dword dwfileoffsetlow,

__in size_t dwnumberofbytestomap

);

bool winapi unmapviewoffile(

__in lpcvoid lpbaseaddress

);

handle winapi createfile(

__in lpctstr lpfilename,

__in dword dwdesiredaccess,

__in dword dwsharemode,

__in_opt lpsecurity_attributes lpsecurityattributes,

__in dword dwcreationdisposition,

__in dword dwflagsandattributes,

__in_opt handle htemplatefile

);

bool winapi closehandle(

__in handle hobject

);

各程式語言的記憶體分配方式

c 的記憶體分配方式 1 棧區 stack 由編譯器自動分配釋放,在不需要的時候自動清除。用於存放函式的引數 區域性變數等。在乙個程序中,位於使用者虛擬位址空間頂部的是使用者棧,編譯器用它來實現函式的呼叫。操作方式類似資料結構中的棧 後進先出 2 堆區 heap 就是那些由 new 分配的記憶體塊,...

mmap實現共享記憶體

mmap概念 mmap將乙個檔案或者其它物件對映進記憶體。檔案被對映到多個頁上,如果檔案的大小不是所有頁的大小之和,最後乙個頁不被使用的空間將會清零。mmap在使用者空間對映呼叫系統中作用很大。mmap操作提供了一種機制,讓使用者程式直接訪問裝置記憶體,這種機制,相比較在使用者空間和核心空間互相拷貝...

記憶體對映檔案實現共享記憶體

記憶體對映檔案程序間共享記憶體 記憶體對映檔案的另乙個功能是在程序間共享資料,它提供了不同程序共享記憶體的乙個有效 且簡單的方法。後面的許多例子都要用到共享記憶體。共享記憶體主要是通過對映機制實現的。windows 下程序的位址空間在邏輯上是相互隔離的,但在物理上卻是重疊的。所謂的重 對映檔案物件時...