共享內存是在內存中單獨開辟的一段內存空間,這段內存空間有自己特有的數據結構,包括訪問權限、大小和最近訪問的時間等。
共享內存 IPC 原理
共享內存進程間通信機制主要用于實現進程間大量的數據傳輸,下圖所示為進程間使用共享內存實現大量數據傳輸的示意圖:
共享內存是在內存中單獨開辟的一段內存空間,這段內存空間有自己特有的數據結構,包括訪問權限、大小和最近訪問的時間等。該數據結構定義如下:
from /usr/include/linux/shm.hstruct shmid_ds {struct ipc_perm shm_perm; /* operation perms 操作權限 */int shm_segsz; /* size of segment (bytes) 段長度大小 */__kernel_time_t shm_atime; /* last attach time 最近attach時間 */__kernel_time_t shm_dtime; /* last detach time 最近detach時間 */__kernel_time_t shm_ctime; /* last change time 最近change時間 */__kernel_ipc_pid_t shm_cpid; /* pid of creator 創建者pid */__kernel_ipc_pid_t shm_lpid; /* pid of last operator 最近操作pid */unsigned short shm_nattch; /* no. of current attaches */unsigned short shm_unused; /* compatibility */void *shm_unused2; /* ditto - used by DIPC */void *shm_unused3; /* unused */|};
兩個進程在使用此共享內存空間之前,需要在進程地址空間與共享內存空間之間建立聯系,即將共享內存空間掛載到進程中。
系統對共享內存做了以下限制:
#define SHMMAX 0x2000000 /* max shared seg size (bytes) 最大共享段大小 */#define SHMMIN 1 /* min shared seg size (bytes) 最小共享段大小 */#define SHMMNI 4096 /* max num of segs system wide */#define SHMALL (SHMMAX/getpagesize()*(SHMMNI/16))|define SHMSEG SHMMNI /* max shared segs per process */Linux 共享內存管理
1.創建共享內存
#include
/** 第一個參數為 key 值,一般由 ftok() 函數產生* 第二個參數為欲創建的共享內存段大小(單位為字節)* 第三個參數用來標識共享內存段的創建標識*/
int shmget(key_t key, size_t size, int shmflg);
2.共享內存控制
#include
/** 第一個參數為要操作的共享內存標識符* 第二個參數為要執行的操作* 第三個參數為 shmid_ds 結構的臨時共享內存變量信息*/
int shmctl(int shmid, int cmd, struct shmid_ds *buf);
3.映射共享內存對象
系統調用 shmat() 函數實現將一個共享內存段映射到調用進程的數據段中,并返回內存空間首地址,其函數聲明如下:
#include
/** 第一個參數為要操作的共享內存標識符* 第二個參數用來指定共享內存的映射地址,非0則為此參數,為0的話由系統分配* 第三個參數用來指定共享內存段的訪問權限和映射條件*/
void *shmat(int shmid, const void *shmaddr, int shmflg);
4.分離共享內存對象
在使用完畢共享內存空間后,需要使用 shmdt() 函數調用將其與當前進程分離。函數聲明如下:
#include
/** 參數為分配的共享內存首地址*/
int shmdt(const void *shmaddr);共享內存在父子進程間遵循的約定
1.使用 fork() 函數創建一個子進程后,該進程繼承父親進程掛載的共享內存。
2.如果調用 exec() 執行一個新的程序,則所有掛載的共享內存將被自動卸載。
3.如果在某個進程中調用了 exit() 函數,所有掛載的共享內存將與當前進程脫離關系。
程序實例
申請一段共享內存,父進程在首地址處存入一整數,子進程讀出。
#include#include
/* 申請共享內存 */
shm_id = shmget((key_t)1004, SHM_SIZE, IPC_CREAT | 0600);
/* 映射共享內存到進程地址空間 */
ptr = (int*)shmat(shm_id, 0, 0);printf("Attach addr is %p ", ptr);*ptr = 1004;printf("The Value of Parent is : %d ", *ptr);if((pid=fork()) == -1){perror("fork Err");exit(0);}else if(!pid){printf("The Value of Child is : %d ", *ptr);exit(0);}else{sleep(1);
/* 解除映射 */
shmdt(ptr);
/* 刪除共享內存 */
shmctl(shm_id, IPC_RMID, 0);}return 0;}
輸出結果:
-
Linux
+關注
關注
87文章
11339瀏覽量
210118 -
共享內存
+關注
關注
0文章
16瀏覽量
8329
原文標題:架構師進階:Linux進程間如何共享內存?
文章出處:【微信號:magedu-Linux,微信公眾號:馬哥Linux運維】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論