摘自:http://club.it.sohu.com/read_elite.php?b=program&a=186962
本文所有程式均應在unix系作業系統下編譯執行。
第九章:利用共享記憶體實現程序間通訊
在兩個程序間共享資料的方法,至今為止我們只說過利用管道。管道只是利用了輸入輸出重定向的原理,非常簡單。而且只能在父子程序間使用。很多場合下這種方法是無法滿足我們的要求的。
那麼現在,我們又有了一種新的方法——利用共享記憶體(shared memory)。這可以使我們在任意兩個程序間傳遞資料,而且也是相對簡單容易實現的乙個方法。
注意:在正常情況下,乙個程序的所使用的記憶體區是不允許其它程序訪問的。這裡我們要開闢的共享記憶體是例外。
我們來做乙個簡單的剪貼簿。從標準輸入向mcut輸入資料,mcut將其放在共享記憶體中,然後mpaste從共享記憶體中讀出資料並顯示。
/* mcut.c */
#include
#include
#include
#include
int main()
*in_ptr = '/0' ;
in_ptr = in_data ;
// 開始寫入共享記憶體
while( *in_ptr != '/0' )
*pos = '/0' ;
shmdt( head ); // 禁止本程序使用這塊記憶體
return 0;
}/* mpaste.c */
#include
#include
#include
#include
int main()
*out_ptr = '/0' ;
printf( %s/n , out_data );
fflush( stdout );
shmdt( head ); // 禁止本程序使用這塊共享記憶體
return 0;
}如何?明白多少了?
要使用共享記憶體,應該有如下步驟:
1.開闢一塊共享記憶體 shmget()
2.允許本程序使用共某塊共享記憶體 shmat()
3.寫入/讀出
4.禁止本程序使用這塊共享記憶體 shmdt()
5.刪除這塊共享記憶體 shmctl()或者命令列下ipcrm
上面的程式中用到了如下函式,我們一一解釋一下。
首先是ftok()。它有兩個引數,乙個是字串,乙個是字元。字串一般用當前程序的程式名,字元一般用來標記這個識別符號所標識的共享記憶體是這個程序所開闢的第幾個共享記憶體。ftok()會返回乙個key_t型的值,也就是計算出來的識別符號的值。
其次,操作共享記憶體,我們用到了下面的函式
#include
#include
#include
int shmget( key_t shmkey , int shmsiz , int flag );
void *shmat( int shmid , char *shmaddr , int shmflag );
int shmdt( char *shmaddr );
shmget()是用來開闢/指向一塊共享記憶體的函式。引數定義如下:
key_t shmkey 是這塊共享記憶體的識別符號。如果是父子關係的程序間通訊的話,這個識別符號用ipc_private來代替。但是剛才我們的兩個程序沒有任何關係,所以就用ftok()算出來乙個識別符號使用了。
int shmsiz 是這塊記憶體的大小.
int flag 是這塊記憶體的模式(mode)以及許可權標識(關於許可權的意思,請參閱本系列第五章)。
模式可取如下值: 新建:ipc_creat
使用已開闢的記憶體:ipc_alloc
如果識別符號以存在,則返回錯誤值:ipc_excl
然後將「模式」 和「許可權標識」進行「或」運算,做為第三個引數。
如: ipc_creat | ipc_excl | 0666
這個函式成功時返回共享記憶體的id,失敗時返回-1。
shmat()是用來允許本程序訪問一塊共享記憶體的函式。
int shmid是那塊共享記憶體的id。
char *shmaddr是共享記憶體的起始位址
int shmflag是本程序對該記憶體的操作模式。如果是shm_rdonly的話,就是唯讀模式。其它的是讀寫模式
成功時,這個函式返回共享記憶體的起始位址。失敗時返回-1。
shmdt()與shmat()相反,是用來禁止本程序訪問一塊共享記憶體的函式。
引數char *shmaddr是那塊共享記憶體的起始位址。
成功時返回0。失敗時返回-1。
此外,還有乙個用來控制共享記憶體的shmctl()函式如下:
#include
#include
#include
int shmctl( int shmid , int cmd , struct shmid_ds *buf );
int shmid是共享記憶體的id。
int cmd是控制命令,可取值如下:
ipc_stat 得到共享記憶體的狀態
ipc_set 改變共享記憶體的狀態
ipc_rmid 刪除共享記憶體
struct shmid_ds *buf是乙個結構體指標。ipc_stat的時候,取得的狀態放在這個結構體中。如果要改變共享記憶體的狀態,用這個結構體指定。
返回值: 成功:0
失敗:-1
剛才我們的mpaste.c程式中還可以加入這樣幾句。
struct shmid_ds buf;
... ...
shmctl( shmid , ipc_stat , &buf ); // 取得共享記憶體的狀態
... ...
shmctl( shmid , ipc_rmid , &buf ); // 刪除共享記憶體
注意!!!!!!!!!:在使用共享記憶體,結束程式退出後。如果你沒在程式中用shmctl()刪除共享記憶體的話,一定要在命令列下用ipcrm命令刪除這塊共享記憶體。你要是不管的話,它就一直在那兒放著了。
簡單解釋一下ipcs命令和ipcrm命令。
取得ipc資訊:
ipcs [-m|-q|-s]
-m 輸出有關共享記憶體(shared memory)的資訊
-q 輸出有關資訊佇列(message queue)的資訊
-s 輸出有關「遮斷器」(semaphore)的資訊
%ipcs -m
刪除ipc
ipcrm -m|-q|-s shm_id
%ipcrm -m 105
共享記憶體實現程序間通訊
1 物理檔案控制代碼 任何可以獲得的物理檔案控制代碼,如果你需要建立乙個物理檔案無關的記憶體對映也無妨,將它設定成為 0xffffffff invalid handle value 就可以了.如果需要和物理檔案關聯,要確保你的物理檔案建立的時候的訪問模式和 保護設定 匹配,比如 物理檔案唯讀,記憶體...
程序間通訊 共享記憶體
下面是自己寫的乙個簡單的共享記憶體的程序間通訊的例子。共享記憶體是用於程序間大量資料共享的一種方法。include include include include include include int main if buf1 shmat shmid,0,0 void 1 strcpy buf1,...
程序間通訊 共享記憶體
共享記憶體是被多個程序共享的一部分物理記憶體。共享記憶體是程序間共享資料的一種最快的方式,乙個程序向共享記憶體區域寫入資料,共享這個記憶體區域的所有程序就可以立刻看到其中的內容。共享記憶體實現分兩個步驟 建立共享記憶體,使用shmget函式 對映共享記憶體,使用shmat函式 共享記憶體是一種最為高...