標籤:記憶體管理 核心
大多數共用記憶體的具體實現,都是把由不同進程之間共用的記憶體映射為同一段實體記憶體。 多個進程都把該實體記憶體區域對應到自己的虛擬位址空間,這些進程就都可以直接存取該共用記憶體地區,從而可以通過該地區進行通訊。
共用記憶體允許兩個不相關的進程訪問同一段實體記憶體, 由於資料不需要在不同的進程間複製,所以它是在兩個正在啟動並執行進程之間傳遞資料的一種非常有效方式,一個進程向共用記憶體地區寫入資料,共用該地區的所有進程就可以立刻看到其中的資料內容。
注意:
1.如所示,共用虛擬記憶體的頁面,出現在每一個共用該頁面的進程的頁表中。但是它不需要在所有進程的虛擬記憶體中都有相同的虛擬位址。
2.共用記憶體的同步控制必須由程式員來負責。用共用記憶體來提供對大塊記憶體地區的有效訪問,同時通過傳遞小道訊息來同步對該記憶體的訪問。
5.2 共用記憶體函數
函數原型:
#include <sys/types.h> #include <sys/ipc.h> #include <sys/shm.h> int shmget(key_t key, int size, int flag); void* shmat(int shmid, const void *addr, int flag); int shmdt(char *shmaddr);int shmctl(int shmid, int cmd, struct shmid_ds *buf);
函數描述:
shmget函數:用於開闢或指向一塊共用記憶體,返回獲得共用記憶體地區的ID,如果不存在指定的共用地區就建立相應的地區。 keyt key: 共用記憶體的標識符。如果是父子關係的處理序間通訊的話,這個標識符用IPC_PRIVATE來代替。 如果兩個進程沒有任何關係,所以就用ftok()算出來一個標識符(或者自己定義一個)使用了。 int size: 以位元組為單位指定需要共用的記憶體容量。 int flag: 包含9個位元的許可權標誌,它是這塊記憶體的模式(mode)以及許可權標識。 模式可取如下值: IPC_CREAT 建立(如果已建立則返回目前共用記憶體的id) IPC_EXCL 與 IPC_CREAT結合使用,如果已建立則返回錯誤 將“模式” 和“許可權標識”進行或運算,做為第三個參數。如:IPC_CREAT | IPC_EXCL | 0640 其中0640為許可權標識,4/2/1 分別表示讀/寫/執行3種許可權,第一個0是UID,第一個6(4+2)表示擁 有者的許可權,第二個4表示同組許可權,第3個0表示他人的許可權。 函數調用成功時返回共用記憶體的ID,失敗時返回-1。 註:建立共用記憶體時,shmflg參數至少需要 IPC_CREAT | 許可權標識,如果只有IPC_CREAT 則申請的地址都是 k=0xffffffff,不能使用;shmat函數:用來允許本進程訪問一塊共用記憶體的函數。 第一次建立共用記憶體時,它不能任何進程訪問,要想啟用對該共用記憶體的訪問,必須將其串連到一個進程的地址空間中。 shmat函數就是用來完成此工作的。 int shmid : 共用記憶體的ID,即共用記憶體的標識。 char *shmaddr: 共用記憶體串連到進程中的起始地址,如果shmaddr為NULL,核心會把共用記憶體映射到系統選定的地 址空間中;如果shmaddr不為NULL,核心會把共用記憶體映射到shmaddr指定的位置。 註:一般情況下我們很少需要控制共用記憶體串連的地址,通常都是讓系統來選擇一個地址,否則就會使應 用程式對硬體的依賴性過高。所以一般把shmaddr設為NULL。 int shmflag : 本進程對該記憶體的操作模式,可以由兩個取值:SHM_RND和SHM_RDONLY。SHM_RND為讀寫入模式, SHM_RDONLY是唯讀模式。需要注意的是,共用記憶體的讀寫權限由它的屬主、它的存取權限和當 前進程的屬主共同決定。如果當shmflg & SM_RDONLY為true時,即使該共用記憶體的存取權限允許寫操 作,它也不能被寫入。該參數通常會被設為0。 函數調用成功時,返回共用記憶體的起始地址,失敗時返回-1。shmdt函數:用於函數刪除本進程對這塊記憶體的使用。 shmdt()與shmat()相反,是用來禁止本進程訪問一塊共用記憶體的函數。 char *shmaddr 是那塊共用記憶體的起始地址。 函數調用成功時返回0,失敗時返回-1。shmctl函數: 控制對這塊共用記憶體的使用。 int shmid: 共用記憶體的ID,即共用記憶體標識。 int cmd : 控制命令,表示要採取的動作,可取值如下: IPC_STAT 得到共用記憶體的狀態:把shmid_ds結構中的資料設定為共用記憶體的當前關聯值 IPC_SET 改變共用記憶體的狀態:把共用記憶體的當前關聯值設定為shmid_ds結構中給出的值 IPC_RMID 刪除共用記憶體段 shmid_ds結構至少包含以下成員: struct shmid_ds { uid_t shm_perm.uid; uid_t shm_perm.gid; uid_t shm_perm.mode; } struct shmid_ds *buf: 一個結構體指標。IPC_STAT的時候,取得的狀態放在這個結構體中。 如果要改變共用記憶體的狀態,用這個結構體指定。 函數調用成功時返回0,失敗時返回-1。
Linux處理序間通訊--shmget()共用記憶體(一)