程序間共享記憶體(一)

2021-06-21 03:14:13 字數 2059 閱讀 9966

system v程序間通訊(ipc)包括3種機制:訊息佇列,訊號量,共享記憶體。

訊息佇列和訊號量均是核心空間的系統物件,經由它們的資料需要在核心和使用者空間進行額外的資料拷貝;而共享記憶體和訪問它的所有應用程式均同處於使用者空間,應用程序可以通過位址對映的方式直接讀寫記憶體,從而獲得非常高的通訊效率。

system v為共享記憶體定義了下列api介面函式:

#include #include #include key_t ftok(const char *pathname,int proj_id);

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

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

int shmdt(void *shmaddr);

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

ftok:函式用於聲稱乙個鍵值:key_t key,該鍵值將作為共享記憶體物件的唯一性識別符號,並提供給為shmget函式作為其輸入引數;ftok函式的輸入引數包括乙個檔案(或目錄)路徑名:pathname,以及乙個額外的數字:proj_id,其中pathname所指定的檔案(或目錄)要求必須已經存在,且proj_id不可為0;

shmget :函式用於建立(或者獲取)乙個由key鍵值指定的共享記憶體物件,返回該物件的系統識別符號:shmid;

shmat :函式用於建立呼叫程序與由識別符號shmid指定的共享記憶體物件之間的連線;

shmdt :函式用於分離呼叫程序與共享記憶體物件之間的連線;

shmctl :函式用於對已建立的共享記憶體物件進行查詢,設值,刪除等操作。

根據pathname指定的檔案(或目錄)名稱,及proj_id引數指定的數字,ftok函式為ipc物件生成乙個唯一性的鍵值。

在實際應用中,很容易產生的乙個理解是,在proj_id相同的情況下,只要檔案(或目錄)名稱不變,就可以確保ftok返回始終一致的鍵值。然而,這個理解並非完全正確,有可能給應用開發埋下很隱晦的陷阱。

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

aix、solaris、hp-ux均明確指出,key檔案被刪除並重建後,不保證通過ftok得到的鍵值不變。

aix上:

對於64位程序,同一程序可連線最多268435456個共享記憶體段;

對於32位程序,同一程序可連線最多11個共享記憶體段,除非 使用擴充套件的shmat;

事實上,同時擁有幾十個甚至上百個處理執行緒的應用並不少見。對於32位程序,一旦超過這個限制值,則所有後續的處理執行緒都將無法正常工作,從而導致應用執行失敗。

在hp-ux平台上,如同時執行32位應用和64位應用,且它們訪問的是乙個相同的共享記憶體區,則會遇到相容性問題。

在hp-ux中,應用程式設值ipc_creat標誌呼叫shmget,所建立的共享記憶體區,只可被同型別的應用所訪問;即32位應用程式所建立的共享記憶體區只可被其他的32位應用程式訪問,同樣的,64位應用程式所建立的共享記憶體區只可被其他的64位應用程式訪問。

如果,32位應用企圖訪問乙個由64位應用建立的共享記憶體區,則會在呼叫shmget時失敗,得到einval錯誤碼

解決方案:當64位應用建立共享記憶體時,合併ipc_creat標誌,同時給定ipc_share32標誌:

shmget(mem_key,size,0666|ipc_creat|ipc_share32);

對於32位應用,設定ipc_share32標誌不會帶來任何問題,即,無論應用程式將被編譯為32位還是64位模式,都可採用如上相同的**;並由此解決32位應用和64位應用在共享記憶體訪問上的相容性問題。

程序間共享記憶體

位於系統的交換分割槽 include incude int shmget key t key,size t size,int shm ipc excl ipc creat一起使用可確保共享記憶體已存在時返回錯誤 void shmat int shm id,const void shm addr,in...

程序間通訊 共享記憶體

下面是自己寫的乙個簡單的共享記憶體的程序間通訊的例子。共享記憶體是用於程序間大量資料共享的一種方法。include include include include include include int main if buf1 shmat shmid,0,0 void 1 strcpy buf1,...

linux 程序間共享記憶體

可以採用sysv的shmget shmat 實現。但是我更喜歡shm open mmap 更簡單。writer.c include include include include include include include include struct ofs stat int main voi...