【Linux系统编程】进程间通信之共享内存
生活随笔
收集整理的這篇文章主要介紹了
【Linux系统编程】进程间通信之共享内存
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
00. 目錄
文章目錄
- 00. 目錄
- 01. 共享內存概述
- 02. 共享內存函數
- 2.1 創建共享內存
- 2.2 共享內存映射
- 2.3 共享內存解除映射
- 2.4 共享內存操作函數
- 03. 案例實戰
- 04. 附錄
01. 共享內存概述
共享內存是進程間通信中最簡單的方式之一。共享內存允許兩個或更多進程訪問同一塊內存,就如同 malloc() 函數向不同進程返回了指向同一個物理內存區域的指針。當一個進程改變了這塊地址中的內容的時候,其它進程都會察覺到這個更改。
共享內存的特點
1)共享內存是進程間共享數據的一種最快的方法。
一個進程向共享的內存區域寫入了數據,共享這個內存區域的所有進程就可以立刻看到其中的內容。
2)使用共享內存要注意的是多個進程之間對一個給定存儲區訪問的互斥。
若一個進程正在向共享內存區寫數據,則在它做完這一步操作前,別的進程不應當去讀、寫這些數據。
02. 共享內存函數
2.1 創建共享內存
#include <sys/ipc.h>#include <sys/shm.h>int shmget(key_t key, size_t size,int shmflg); 功能:創建或打開一塊共享內存區。 參數:key:進程間通信鍵值,ftok() 的返回值。size:該共享存儲段的長度(字節)。shmflg:標識函數的行為及共享內存的權限,其取值如下:IPC_CREAT:如果不存在就創建IPC_EXCL: 如果已經存在則返回失敗位或權限位:共享內存位或權限位后可以設置共享內存的訪問權限,格式和 open() 函數的 mode_t 一樣(open() 的使用請點此鏈接),但可執行權限未使用。 返回值:成功:共享內存標識符。失敗:-1。參考代碼:
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/types.h> #include <sys/ipc.h> #include <sys/shm.h>#define BUFSZ 1024int main(int argc, char *argv[]) {int shmid;key_t key;key = ftok("./", 2015); if(key == -1){perror("ftok");}//創建共享內存shmid = shmget(key, BUFSZ, IPC_CREAT|0666); if(shmid < 0) { perror("shmget"); exit(-1); } return 0; }執行結果:
deng@itcast:/mnt/hgfs/LinuxHome/code.bak2$ gcc 1.c deng@itcast:/mnt/hgfs/LinuxHome/code.bak2$ ./a.out deng@itcast:/mnt/hgfs/LinuxHome/code.bak2$ ipcs -m------------ 共享內存段 -------------- 鍵 shmid 擁有者 權限 字節 連接數 狀態 0x00000000 458752 deng 600 524288 2 目標 0x00000000 1310721 deng 600 524288 2 目標 0x00000000 327682 deng 600 524288 2 目標 0x00000000 917507 deng 600 67108864 2 目標 0x00000000 5439492 deng 600 524288 2 目標 0x00000000 4390917 deng 600 524288 2 目標 0xdf320009 5472262 deng 666 1024 0 deng@itcast:/mnt/hgfs/LinuxHome/code.bak2$2.2 共享內存映射
#include <sys/types.h> #include <sys/shm.h>void *shmat(int shmid, const void *shmaddr, int shmflg); 功能:將一個共享內存段映射到調用進程的數據段中。簡單來理解,讓進程和共享內存建立一種聯系,讓進程某個指針指向此共享內存。 參數:shmid:共享內存標識符,shmget() 的返回值。shmaddr:共享內存映射地址(若為 NULL 則由系統自動指定),推薦使用 NULL。shmflg:共享內存段的訪問權限和映射條件( 通常為 0 ),具體取值如下:0:共享內存具有可讀可寫權限。SHM_RDONLY:只讀。SHM_RND:(shmaddr 非空時才有效) 返回值:成功:共享內存段映射地址( 相當于這個指針就指向此共享內存 )失敗:-12.3 共享內存解除映射
#include <sys/types.h> #include <sys/shm.h>int shmdt(const void *shmaddr); 功能:將共享內存和當前進程分離(僅僅是斷開聯系并不刪除共享內存,相當于讓之前的指向此共享內存的指針,不再指向)。 參數:shmaddr:共享內存映射地址。 返回值:成功:0失敗:-12.4 共享內存操作函數
#include <sys/ipc.h> #include <sys/shm.h>int shmctl(int shmid, int cmd, struct shmid_ds *buf); 功能:共享內存屬性的控制。 參數:shmid:共享內存標識符。cmd:函數功能的控制,其取值如下:IPC_RMID:刪除。(常用 )IPC_SET:設置 shmid_ds 參數,相當于把共享內存原來的屬性值替換為 buf 里的屬性值。IPC_STAT:保存 shmid_ds 參數,把共享內存原來的屬性值備份到 buf 里。SHM_LOCK:鎖定共享內存段( 超級用戶 )。SHM_UNLOCK:解鎖共享內存段。SHM_LOCK 用于鎖定內存,禁止內存交換。并不代表共享內存被鎖定后禁止其它進程訪問。其真正的意義是:被鎖定的內存不允許被交換到虛擬內存中。這樣做的優勢在于讓共享內存一直處于內存中,從而提高程序性能。buf:shmid_ds 數據類型的地址(具體類型請點此鏈接 ),用來存放或修改共享內存的屬性。 返回值:成功:0失敗:-103. 案例實戰
創建兩個進程,在 A 進程中創建一個共享內存,并向其寫入數據,通過 B 進程從共享內存中讀取數據。
寫共享內存代碼
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/types.h> #include <sys/ipc.h> #include <sys/shm.h>#define BUFSZ 512int main(int argc, char *argv[]) {int shmid;int ret;key_t key;char *shmadd;//創建key值key = ftok("../", 2015); if(key == -1){perror("ftok");}//創建共享內存shmid = shmget(key, BUFSZ, IPC_CREAT|0666); if(shmid < 0) { perror("shmget"); exit(-1); }//映射shmadd = shmat(shmid, NULL, 0);if(shmadd < 0){perror("shmat");_exit(-1);}//拷貝數據至共享內存區printf("copy data to shared-memory\n");bzero(shmadd, BUFSZ); // 共享內存清空strcpy(shmadd, "how are you, mike\n");return 0; }讀共享內存代碼
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/types.h> #include <sys/ipc.h> #include <sys/shm.h>#define BUFSZ 512int main(int argc, char *argv[]) {int shmid;int ret;key_t key;char *shmadd;//創建key值key = ftok("../", 2015); if(key == -1){perror("ftok");}system("ipcs -m"); //查看共享內存//打開共享內存shmid = shmget(key, BUFSZ, IPC_CREAT|0666);if(shmid < 0) { perror("shmget"); exit(-1); } //映射shmadd = shmat(shmid, NULL, 0);if(shmadd < 0){perror("shmat");exit(-1);}//讀共享內存區數據printf("data = [%s]\n", shmadd);//分離共享內存和當前進程ret = shmdt(shmadd);if(ret < 0){perror("shmdt");exit(1);}else{printf("deleted shared-memory\n");}//刪除共享內存shmctl(shmid, IPC_RMID, NULL);system("ipcs -m"); //查看共享內存return 0; }04. 附錄
總結
以上是生活随笔為你收集整理的【Linux系统编程】进程间通信之共享内存的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【Linux系统编程】进程间通信之消息队
- 下一篇: 【Linux系统编程】进程和线程的区别