[編程開發]如何使用共享內存

 共享內存作爲一種IPC,用於進程間通信,甚至可以實現用戶程序與內核間的數據交換。現在我們就簡單介紹一下共享內存的幾個系統調用。

創建
第一步要做的是創建一個共享內存結構。
#include <sys/shm.h>
#include <sys/ipc.h>

int shmget (key_t key, int size, int shmflg);

  • key是一個整數值,用來指定一個關鍵字,它可以用於搜尋一個共享內存結構。
  • size表示要創建的共享內存的大小,以字節計算。
  • shmflg爲創建指派屬性。
    • IPC_CREAT表示創建一個新的共享內存結構,若key已經代表了一個結構並且該結構未被刪除,則直接返回這個結構的標識。
    • IPC_EXCL需要與IPC_CREAT一起使用,指定IPC_EXCL後,若key已經關聯了一個共享內存結構,則shmget出錯,返回-1。所以IPC_EXCL可以保證shmget創建一個新的結構。若shmflg爲0,則shmget尋找key關聯的共享內存結構,若找到,返回改結構的標識符,否則返回-1。
    • 若調用成功,則返回得到的共享內存結構標識符,否則返回-1。

連接
創建了一個共享內存結構之後,需要將這個結構和一段存儲區域、一個指針連接起來,才能通過該指針正確訪問共享的內存區域。
#include <sys/types.h>
#include <sys/shm.h>

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

  • shmid是shmget調用得到的共享內存結構標識符。
  • shmaddr指定連接的目的地址。若shmaddr爲0,則由內核選擇目的內存段,並返回該段的指針。若shmaddr不爲0,且shmflg未指定SHM_RND選項,則shmaddr必須爲頁對齊的地址,該地址表示的內存段將被連接;若shmaddr不爲0且shmflg指定了SHM_RND,則連接的地址爲小於shmaddr且最接近shmaddr的SHMLBA的倍數。
  • shmflg指定連接的屬性。除了上面說的SHM_RND外,還可以指定SHM_RDONLY屬性。若指定了SHM_RDONLY,則以只讀方式連接,否則連接的內存是可讀可寫的。
  • 若調用成功則返回得到的存儲區域指針,否則返回-1。

訪問
連接成功後,根據的到的指針,我們就可以根據需要來使用得到的存儲空間了。

控制
我們可以根據需要來設置的到的共享內存結構的屬性,甚至可以實現刪除。
#include <sys/shm.h>
#include <sys/ipc.h>

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

  • shmid是要操作的共享內存結構標識符。
  • cmd用來指定我們要進行的操作。
    • IPC_STAT用來獲得共享內存段的狀態信息,結果保存在buf中
    • IPC_SET用來設置共享內存段的一些狀態信息,在buf的成員shm_perms中預先指定我們想要改變的屬性。
    • IPC_RMID給shmid指定的內存段加上刪除標誌,在該段最後一次斷開連接後,內存將被釋放。
    • SHM_LOCK鎖定內存段以保證不會被訪問。
    • SHM_UNLOCK解除鎖定。
    • SHM_LOCK、SHM_UNLOCK只在Linux系統中有效,並且只有超級用戶纔可以使用。
  • buf保存shmid標識的共享內存結構的信息。

斷開
一般用完共享內存段之後要斷開連接。
#include <sys/types.h>
#include <sys/shm.h>

int shmdt (const void *shmaddr);

  • shmaddr是連接後得到的指針。
  • 若調用成功,返回0,否則返回-1。
  • 注意,斷開操作只是切斷進程與該共享內存的關聯,並不會釋放內存段。(簡直是廢話,不然共享內存還有什麼用!^_^)

以上簡單介紹了幾個調用的功能,使用共享內存的操作順序爲:創建(查找)——連接——控制——訪問——斷開,在確信不用時進行銷燬(實際上是控制的一個特例)。

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