系統程式設計之共享記憶體

2021-10-04 05:56:19 字數 4301 閱讀 9067

1.概述

共享記憶體是程序間通訊中最簡單的方式之一。共享記憶體允許兩個或更多程序訪問同一塊記憶體,就如同 malloc() 函式向不同程序返回了指向同乙個物理記憶體區域的指標。當乙個程序改變了這塊位址中的內容的時候,其它程序都會察覺到這個更改。

2.共享記憶體的特點:

1.共享記憶體是程序間共享資料的一種最快的方法。乙個程序向共享的記憶體區域寫入了資料,共享這個記憶體區域的所有程序就可以立刻看到其中的內容。

2.使用共享記憶體要注意的是多個程序之間對乙個給定儲存區訪問的互斥。若乙個程序正在向共享記憶體區寫資料,則在它做完這一步操作前,別的程序不應當去讀、寫這些資料。

4.共享記憶體的操作

4.1共享記憶體的分配

程序通過呼叫shmget(shared memory get,獲取共享記憶體)來分配乙個共享記憶體塊。

該函式的第乙個引數是乙個用來標識共享記憶體塊的鍵值。彼此無關的程序可以通過指定同乙個鍵以獲取對同乙個共享記憶體塊的訪問。不幸的是,其它程式也可能挑選了同樣的特定值作為自己分配共享記憶體的鍵值,從而產生衝突。用特殊常量ipc_private作為鍵值可以保證系統建立乙個全新的共享記憶體塊。該函式的第二個引數指定了所申請的記憶體塊的大小。因為這些記憶體塊是以頁面為單位進行分配的,實際分配的記憶體塊大小將被擴大到頁面大小的整數倍。第三個引數是一組標誌,通過特定常量的按位或操作來shmget。

所需標頭檔案:

#include

#include

函式:

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

功能:

建立或開啟一塊共享記憶體區。

引數:

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

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

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

ipc_creat:如果不存在就建立

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

返回值:

成功:共享記憶體識別符號。

失敗:-1。

4.2.共享記憶體的對映

要讓乙個程序獲取對一塊共享記憶體的訪問,這個程序必須先呼叫shmat(shared memory attach,繫結到共享記憶體)。將 shmget 返回的共享記憶體識別符號 shmid 傳遞給這個函式作為第乙個引數。該函式的第二個引數是乙個指標,指向您希望用於對映該共享記憶體塊的程序虛擬記憶體位址;如果您指定null則linux會自動選擇乙個合適的位址用於對映。第三個引數是乙個標誌位,

所需標頭檔案:

#include

#include

函式:

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

功能:

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

引數:

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

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

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

shm_rdonly:唯讀。

shm_rnd:(shmaddr 非空時才有效)

返回值:4.3.解除共享記憶體的對映

當乙個程序不再使用乙個共享記憶體塊的時候應通過呼叫shmdt(shared memory detach,脫離共享記憶體塊)函式與該共享記憶體塊脫離。如果當釋放這個記憶體塊的程序是最後乙個使用該記憶體塊的程序,則這個記憶體塊將被刪除。對 exit 或任何exec族函式的呼叫都會自動使程序脫離共享記憶體塊。

所需標頭檔案:

#include

#include

函式:

int shmdt(const void *shmaddr);

功能:

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

引數:返回值:

成功:0

失敗:-1

4.4.共享記憶體的控制

所需的標頭檔案:

#include

#include

函式

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

返回值:

成功:0

失敗:-1

5.實戰**

建立兩個程式,在共享記憶體中寫入乙個為100的數,兩個程序輪流把他讀出然後再減1後寫進去

****1:**

#include

#include

#include

#include

#include

#include

#include

#include

#include

#define shmkey 1233

#define shmsize 4096

intmain()

//對映

void

*p =

shmat

(shmid,

null,0

);if(

null

== p)*(

int*

)p = num;

//把變數寫進記憶體

while(1

)printf

("%d get num = %d\n"

,getpid()

, num)

; num--;*

(int

*)p = num;

usleep

(10000);

}shmdt

(p);

//解除對映

shmctl

(shmid, ipc_rmid,

null);

return0;

}

**2:

#include

#include

#include

#include

#include

#include

#include

#include

#include

#define shmkey 1233

#define shmsize 4096

intmain()

void

*p =

shmat

(shmid,

null,0

);if(

null

== p)

while(1

)printf

("%d get num = %d\n"

,getpid()

, num)

; num--

;usleep

(10000);

}shmdt

(p);

return0;

}同時執行兩個程式:

系統程式設計之程序通訊 共享記憶體

shm com.h define text sz 2048 struct shared use st shm1.c 讀程序 include include include include include include include include shm com.h int main void ...

linux系統程式設計 實現共享記憶體

一 相關的api 1 shmget 建立或者獲取乙個共享記憶體,成功返回共享記憶體id,失敗返回 1。建立共享記憶體 man手冊 man 2 shmget key t 輸入 key就可以 size 共享記憶體的大小以兆對齊 flag 開啟佇列的方式,一般為ipc creat man手冊 man 2 ...

系統程式設計之檔案系統程式設計

系統呼叫 所有的作業系統都提供多種服務的入口點,程式由此向核心請求服務。這些可直接進入核心的入口點被稱為系統呼叫。不同作業系統提供了自己的一套系統呼叫,所以系統呼叫無法實現跨平台使用。而且頻繁地系統呼叫,在使用者態和核心態之間切換,很耗費資源,效率不高。c標準庫提供了操作檔案的標準i o函式庫,與系...