共享內存相關函數

大多數共享內存的具體實現,都是把由不同進程之間共享的內存映射爲同一段物理內存。 多個進程都把該物理內存區域映射到自己的虛擬地址空間,這些進程就都可以直接訪問該共享內存區域,從而可以通過該區域進行通信。

共享內存允許兩個不相關的進程訪問同一段物理內存, 由於數據不需要在不同的進程間複製,所以它是在兩個正在運行的進程之間傳遞數據的一種非常有效的方式,一個進程向共享內存區域寫入數據,共享該區域的所有進程就可以立刻看到其中的數據內容。

注意:
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。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章