POSIX共享記憶體
在Linux中,POSIX共享記憶體物件駐留在tmpfs偽檔案系統中。系統預設掛載在/dev/shm目錄下。當呼叫shm_open函式建立或開啟POSIX共享記憶體物件時,系統會將建立/開啟的共享記憶體檔案放到/dev/shm目錄下。
建立共享記憶體的基本步驟是:
程式執行shm_open函式建立了共享記憶體區域,此時會在/dev/shm/建立共享記憶體檔案.
int shm_open(const char *name, int oflag, mode_t mode); /* 建立或開啟一個共享記憶體,成功返回一個整數的檔案描述符,錯誤返回-1。 1.name:共享記憶體區的名字; 2.oflag標誌位: open的標誌一樣,一般填寫O_CREAT|O_TRUNC|O_RDWR。 3.mode許可權位: open的mode一樣 */
通過ftruncate函式改變shm_open建立共享記憶體的大小為頁大小sysconf(_SC_PAGE_SIZE)整數倍,如果不執ftruncate函式的話,會報Bus error的錯誤。
int ftruncate(int fd, off_t length); /*函式說明:ftruncate()會將引數fd指定的檔案大小改為引數length指定的大小。引數fd為已開啟的檔案描述詞,而且必須是以寫入模式開啟的檔案。如果原來的檔案大小比引數length大,則超過的部分會被刪去。 返 回 值:0、-1 錯誤原因:errno EBADF 引數fd檔案描述詞為無效的或該檔案已關閉 EINVAL 引數fd為一socket並非檔案,或是該檔案並非以寫入模式開啟 */
void* mmap(void* start,size_t length,int prot,int flags,int fd,off_t offset); /*函式說明:mmap()必須以PAGE_SIZE為單位進行對映。 start: 對映區的開始地址,設定為0時表示由系統決定對映區的起始地址。 length: 對映區的長度,長度單位是以位元組為單位,不足一記憶體頁按一記憶體頁處理 prot: 期望的記憶體保護標誌,不能與檔案的開啟模式衝突。是以下的某個值,可以通過或運算合理地組合在一起 PROT_EXEC 頁內容可以被執行 PROT_READ 頁內容可以被讀取 PROT_WRITE 頁可以被寫入 PROT_NONE 頁不可訪問 flags: 指定對映物件的型別,對映選項和對映頁是否可以共享。它的值可以是一個或者多個以下位的組合體 MAP_SHARED 與其它所有對映這個物件的程式共享對映空間。對共享區的寫入,相當於輸出到檔案。 直到msync()或者munmap()被呼叫,檔案實際上不會被更新。 MAP_PRIVATE 建立一個寫入時拷貝的私有對映。記憶體區域的寫入不會影響到原檔案。這個標誌和以 上標誌是互斥的,只能使用其中一個。 MAP_LOCKED 鎖定對映區的頁面,從而防止頁面被交換出記憶體。 fd: 有效的檔案描述符。 offset: 被對映物件內容的起點。 成功返回共享記憶體地址,失敗返回MAP_FAILED */
通過munmap解除安裝共享記憶體
int munmap(void* start,size_t length); /* * start:共享記憶體地址 * length:共享記憶體大小 */
int shm_unlink(const char *name); /* *name:記憶體共享檔案 */
我們用下面的源程式對POSIX共享記憶體進行測試,如下shmen_write.c:
void error_print(char *msg) { perror(msg); exit(-1); } int main (int argc, char *argv[]) { int ret, i; const char *memname = "/mymem"; size_t mem_size = sysconf(_SC_PAGE_SIZE); int fd = shm_open(memname, O_CREAT|O_TRUNC|O_RDWR, 0666); if (fd == -1) error_print("shm_open"); ret = ftruncate(fd, mem_size); if (ret != 0) error_print("ftruncate"); void *ptr = mmap(0, mem_size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); if (ptr == MAP_FAILED) error_print("MMAP"); close(fd); for(i = 0; i < 20; i++) { sprintf((char*)ptr, "data %d", i); printf("write data %s\n", (char*)ptr); } ret = munmap(ptr, mem_size); if (ret != 0) error_print("munmap"); ret = shm_unlink(memname); if (ret != 0) error_print("shm_unlink"); return 0; }
編譯程式shmen_write.c
gcc shmen_write.c -o shmen_write -lrt
shmen_read.c
void error_print(char *msg) { perror(msg); exit(-1); } int main (int argc, char *argv[]) { int ret, i; const char *memname = "/mymem"; //共享記憶體檔案以/開頭,可以更好相容不同系統 struct stat statbuf; size_t mem_size = 2 * sysconf(_SC_PAGE_SIZE); int fd = shm_open(memname, O_CREAT|O_TRUNC|O_RDWR, 0666); if (fd == -1) error_print("shm_open"); ret = ftruncate(fd, mem_size); if (ret != 0) error_print("ftruncate"); void *ptr = mmap(0, mem_size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); if (ptr == MAP_FAILED) error_print("MMAP"); close(fd); for(i = 0; i < 20; i++) { printf("read data %s\n", (char*)ptr); sleep(1); } ret = munmap(ptr, mem_size); if (ret != 0) error_print("munmap"); ret = shm_unlink(memname); if (ret != 0) error_print("shm_unlink"); return 0; }
編譯程式shmen_read.c
gcc shmen_read.c -o shmen_read -lrt
先執行shmem_write,再執行shmem_read.
相關文章
- POSIX 共享記憶體記憶體
- 共享記憶體記憶體
- Golang 共享記憶體Golang記憶體
- oracle 共享記憶體Oracle記憶體
- nginx共享記憶體分析Nginx記憶體
- QT之共享記憶體QT記憶體
- 共享記憶體函式記憶體函式
- shmget() -- 建立共享記憶體記憶體
- SGA與共享記憶體記憶體
- linux共享記憶體Linux記憶體
- 自動共享記憶體管理 自動記憶體管理 手工記憶體管理記憶體
- Qt共享記憶體QSharedMemoryQT記憶體
- Linux共享記憶體(二)Linux記憶體
- 修改/dev/shm共享記憶體dev記憶體
- 共享記憶體分段問題記憶體
- SGA與共享記憶體2記憶體
- 【記憶體管理】Oracle如何使用ASMM自動共享記憶體管理記憶體OracleASM
- nginx中共享記憶體的使用Nginx記憶體
- 程式間通訊---共享記憶體記憶體
- Linux共享記憶體的管理Linux記憶體
- 共享記憶體相關(ipcs/ipcrm)記憶體
- aix 共享記憶體段大小限制AI記憶體
- linux共享記憶體段研究Linux記憶體
- aix 共享記憶體段問題AI記憶體
- 第8章 管理共享記憶體記憶體
- UNIX共享記憶體的程式(轉)記憶體
- OpenResty 和 Nginx 的共享記憶體區是如何消耗實體記憶體的RESTNginx記憶體
- Android匿名共享記憶體(Ashmem)原理Android記憶體
- 程式間通訊之共享記憶體記憶體
- 修改OracleLinux共享記憶體的大小OracleLinux記憶體
- SGA與共享記憶體的關係記憶體
- 程序間通訊(3)-共享記憶體記憶體
- Linux釋放記憶體及手動釋放Oracle共享記憶體段Linux記憶體Oracle
- Golang併發之共享記憶體變數Golang記憶體變數
- Linux共享記憶體的核心實現Linux記憶體
- 解決ORACLE共享記憶體不足的方法Oracle記憶體
- opracle 共享記憶體 /etc/sysctl.conf記憶體
- linux下的記憶體共享引數Linux記憶體