IPC 共享記憶體

2021-08-07 10:45:00 字數 3702 閱讀 6511

程序可以將同一段共享記憶體連線到它們自己的位址空間中,所有程序都可以訪問共享記憶體中的位址。共享記憶體並未提供同步機制,使用訊號量進行同步。

共享記憶體的特點:

1)共享記憶體是程序間共享資料的一種最快的方法。

乙個程序向共享的記憶體區域寫入了資料,共享這個記憶體區域的所有程序就可以立刻看到其中的內容。

2)使用共享記憶體要注意的是多個程序之間對乙個給定儲存區訪問的互斥。

若乙個程序正在向共享記憶體區寫資料,則在它做完這一步操作前,別的程序不應當去讀、寫這些資料。

建立或者開啟,shmget

對映,shmat

解除對映,shmdt

釋放,shmctl

ipcs ipcmk ipcrm

檢視共享記憶體

ipcs -m

key shmid owner perms bytes nattch status

0x00000000 3309582 fengqian 600 524288 2 dest

0x00000000 18022415 fengqian 600 524288 2 dest

0x0119079d 36044816 fengqian 600 1024 1

nattch:當前有多少個程序對映到這塊個共享記憶體,即呼叫shmat後+1,shmdt後-1。

status:狀態,空或者dest

注意:key_t ftok(const char *pathname, int proj_id);

pathname: 指定的檔名,該檔案必須是存在而且可以訪問

proj_id:子序號,只有8個位元被使用(0-255)

當成功執行時,返回乙個key_t值,失敗返回-1

實際應 用中,很容易產生的乙個理解是,在proj_id相同的情況下,只要檔案(或目錄)名稱不變,就可以確保ftok返回始終一致的鍵值。然而,這個理解並非 完全正確,有可能給應用開發埋下很隱晦的陷阱。因為ftok的實現存在這樣的風險,即在訪問同一共享記憶體的多個程序先後呼叫ftok函式的時間段中,如果 pathname指定的檔案(或目錄)被刪除且重新建立,則檔案系統會賦予這個同名檔案(或目錄)新的i節點資訊,於是這些程序所呼叫的ftok雖然都能 正常返回,但得到的鍵值卻並不能保證相同。由此可能造成的後果是,原本這些程序意圖訪問乙個相同的共享記憶體物件,然而由於它們各自得到的鍵值不同,實際上 程序指向的共享記憶體不再一致;如果這些共享記憶體都得到建立,則在整個應用執行的過程中表面上不會報出任何錯誤,然而通過乙個共享記憶體物件進行資料傳輸的目 的將無法實現。

檔案刪除建立後inode不一樣,參考inode原理。

int shmget(key_t key, size_t size,int shm***);

key:程序間通訊鍵值,ftok() 的返回值。

size:該共享儲存段的長度(位元組)。

shm***:標識函式的行為及共享記憶體的許可權,其取值如下:

ipc_creat:如果不存在就建立

ipc_excl: 如果已經存在則返回失敗

位或許可權位:共享記憶體位或許可權位後可以設定共享記憶體的訪問許可權,格式和 open() 函式的 mode_t 一樣,但可執行許可權未使用。

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

功能:

將乙個共享記憶體段對映到呼叫程序的資料段中。簡單來理解,讓程序和共享記憶體建立一種聯絡,讓程序某個指標指向此共享記憶體。

引數:

shmid:共享記憶體識別符號,shmget() 的返回值。

shmaddr:共享記憶體對映位址(若為 null 則由系統自動指定),推薦使用 null。

shm***:共享記憶體段的訪問許可權和對映條件( 通常為 0 ),具體取值如下:

0:共享記憶體具有可讀可寫許可權。

shm_rdonly:唯讀。

shm_rnd:(shmaddr 非空時才有效)

返回值:

成功:共享記憶體段對映位址( 相當於這個指標就指向此共享記憶體 )

失敗:-1

int shmdt(const void *shmaddr);

功能:

將共享記憶體和當前程序分離( 僅僅是斷開聯絡並不刪除共享記憶體,相當於讓之前的指向此共享記憶體的指標,不再指向)。

返回值:

成功:0

失敗:-1

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

功能:

共享記憶體屬性的控制。

引數:

shmid:共享記憶體識別符號。

cmd:函式功能的控制,其取值如下:

ipc_rmid:刪除。(常用 )

ipc_set:設定 shmid_ds 引數,相當於把共享記憶體原來的屬性值替換為 buf 裡的屬性值。

ipc_stat:儲存 shmid_ds 引數,把共享記憶體原來的屬性值備份到 buf 裡。

shm_lock:鎖定共享記憶體段( 超級使用者 )。

shm_unlock:解鎖共享記憶體段。

shm_lock 用於鎖定記憶體,禁止記憶體交換。並不代表共享記憶體被鎖定後禁止其它程序訪問。其真正的意義是:被鎖定的記憶體不允許被交換到虛擬記憶體中。這樣做的優勢在於讓共享記憶體一直處於記憶體中,從而提高程式效能。

#include 

#include

#include

#include

#include

#include

#include

#define shm_size 1024

//ipc_creat 如果不存在就建立

//ipc_excl 如果已經存在則返回失敗

#define shm_mode (shm_r | shm_w | ipc_creat)

#define proj_id 0x01

#define tag 0x55000055

struct sharememory;

int main(int argc, char *argv)

printf("shmid[%d]\n", shmid);

//對映

shmaddr = shmat(shmid, null, 0);

if (shmaddr == (void*)-1)

sharememory *stshm = (sharememory*)shmaddr;

if (stshm->tag == tag)

printf("write data in share memory\n");

bzero(shmaddr, shm_size);

stshm->tag = tag;

strcpy((char*)stshm->data, "hello\n");

printf("enter to destory share memory...\n");

getchar();

//刪除對映

ret = shmdt(shmaddr);

if (ret < 0)

//刪除共享記憶體

ret = shmctl(shmid, ipc_rmid, null);

if (ret < 0)

return

0;}

參考

IPC 共享記憶體

共享記憶體 shared memory 是最簡單的程序間通訊方式,它允許多個程序訪問相同的記憶體,乙個程序改變其中的資料後,其他的程序都可以看到資料的變化。共享記憶體是程序間最快速的通訊方式 程序共享同一塊記憶體空間。訪問共享記憶體和訪問私有記憶體一樣快。不需要系統呼叫和核心入口。不造成不必要的記憶...

IPC 共享記憶體

a 意義 多個程序共享一部分物理記憶體。訪問快,方便 b 先建立共享記憶體 int shmget key t key,int size,int shm 1.key 標誌共享記憶體的鍵值 0 ipc private a key 0 a 意義 多個程序共享一部分物理記憶體。訪問快,方便 b 先建立共享記...

IPC 共享記憶體

共享記憶體是程序間共享資料的一種最快的方法,乙個程序向共享的記憶體區域寫入了資料,共享這個記憶體區域的所有程序就可以立刻看到其中的內容。共享記憶體允許兩個或者多個程序共享給定的儲存區域。使用共享記憶體要注意的是多個程序之間對乙個給定儲存區訪問的互斥。若乙個程序正在向共享記憶體區寫資料,則在它做完這一...