System V共享內存

System V 與Posix 共享內存區

二者的差別是:

(1)Posix共享內存區是先調用shm_open然後再調用mmap,System V 共享內存區是先調用shmget再調用shmat。

(2)Posix共享內存區對象的大小可在任何時刻通過ftruncate修改,而System V 共享內存區對象的大小是在調用shmget創建時固定下來的。

  • 1、int shmget(key_t key, size_t size, int shmflg);  

        key: 函數ftok返回值,或者IPC_PRIVATE ,當使用IPC_PRIVATE時,最好兩個進程空間是共享的,比如父子進程,否則當前進程產生的共享內存標識(返回值),在另一個進程裏面不易得到;

        ftok函數原型爲:key_t ftok(const char *pathname, int proj_id); 參數pathname爲文件絕對路徑名,proj_id爲一個整型標識符,該函數將一個已存在的的路徑名和一個整型標識符轉化成一個key_t值(返回 值),稱爲IPC鍵。

        size:創建新的共享內存大小,當創建一片新的共享內存時,該值爲不爲0的參數。如果是讀取一片共享內存,該值可以爲0。

        shmflg:讀寫權限值組合。IPC_CREAT(創建新的共享內存)或IPC_CREAT|IPC_EXCL(當將要創建的共享內存已經存在時,再試 圖創建將返回EEXIST)。其實IPC_CREAT和IPC_EXCL的組合和open函數的O_CREAT和O_EXCL組合類似。

        函數返回共享內存區的標識。shmxxx函數操作共享內存將使用該函數返回值。該函數類似posix共享內存shm_open函數功能。

​2、void *shmat(int shmid, const void *shmaddr, int shmflg); 

shmid:是函數shmget函數返回的共享內存標識符。

shmaddr: 連接到調用進程地址空間的地址,如果該參數爲NULL,系統選擇一個合適地址;如果shmaddr非空並且shmflg指定了選項SHM_RND,那麼相 應的共享內存鏈接到由shmaddr參數指定的地址向下舍入一個SHMLAB常值。如果shmaddr非空並且shmflg未指定SHM_RND,共享內 存地址鏈接到shmaddr參數指定的地址。

 shmflg:可以指定SHM_RND和SHM_RDONLY(只讀),如果指定SHM_RDONLY選項,那麼調用進程對該片共享內存只有讀權限,否則,進程對該片內存將有讀寫權限。

shmat函數成功返回當前進程共享內存地址,失敗返回(void *)-1;

3、int shmdt(const void *shmaddr);  

shmdt成功返回0,失敗返回-1;​

當shmget創建或打開一個共享內存區後,需要使用函數shmat來將該片共享內存連接到當前進程空間中來,當某一進程使用完共享內存後,使用函數shmdt斷開和共享內存的鏈接。函數shmdt不會刪除指定的共享內存,它只是斷開和該片共享內存的鏈接而已。當一個進程終止後,該進程鏈接的共享內存將自動斷開。​刪除共享內存需要函數shmctl調用IPC_RMID命令來完成。

4、int shmctl(int shmid, int cmd, struct shmid_ds *buf);

shmid:共享內存區標識;        

cmd:對共享內存的操作命令,命令IPC_RMID銷燬(destroy)一片共享內存,銷燬之後所有shmat,shmdt,shmctl對該片內存 操作都將失效,銷燬該共享內存要等到該共享內存引用計數變爲0才進行;IPC_SET命令設置shmid_ds結構成員;IPC_STAT返回當前共享內 存結構;其餘命令查看man手冊。        

buf:爲指向shmid_ds數據結構。

發佈了43 篇原創文章 · 獲贊 6 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章