實驗六 共享儲存區通訊
實驗目的
了解和熟悉共享儲存機制
實驗內容
編制一長度為1k的共享儲存區傳送和接收的程式。
實驗指導
一、共享儲存區
1、共享儲存區機制的概念
共享儲存區(share memory)是unix系統中通訊速度最高的一種通訊機制。該機制可使若干程序共享主存中的某乙個區域,且使該區域出現(對映)在多個程序的虛位址空間中。另一方面,乙個程序的虛位址空間中又可連線多個共享儲存區,每個共享儲存區都有自己的名字。當程序間欲利用共享儲存區進行通訊時,必須先在主存中建立一共享儲存區,然後將它附接到自己的虛位址空間上。此後,程序對該區的訪問操作,與對其虛位址空間的其它部分的操作完全相同。程序之間便可通過對共享儲存區中資料的讀、寫來進行直接通訊。圖示列出二個程序通過共享乙個共享儲存區來進行通訊的例子。其中,程序a將建立的共享儲存區附接到自己的aa』區域,程序b將它附接到自己的bb』區域。
應當指出,共享儲存區機制只為程序提供了用於實現通訊的共享儲存區和對共享儲存區進行操作的手段,然而並未提供對該區進行互斥訪問及程序同步的措施。因而當使用者需要使用該機制時,必須自己設定同步和互斥措施才能保證實現正確的通訊。
二、涉及的系統呼叫
1、shmget( )
建立、獲得乙個共享儲存區。
系統呼叫格式:
shmid=shmget(key,size,flag)
該函式使用標頭檔案如下:
#include
#include
#include
引數定義
int shmget(key,size,flag);
key_t key;
int size,flag;
其中,key是共享儲存區的名字;size是其大小(以位元組計);flag是使用者設定的標誌,如ipc_creat。ipc_creat表示若系統中尚無指名的共享儲存區,則由核心建立乙個共享儲存區;若系統中已有共享儲存區,便忽略ipc_creat。
附:操作允許權 八進位制數
使用者可讀 00400
使用者可寫 00200
小組可讀 00040
小組可寫 00020
其它可讀 00004
其它可寫 00002
控制命令 值
ipc_creat 0001000
ipc_excl 0002000
例:shmid=shmget(key,size,(ipc_creat|0400))
建立乙個關鍵字為key,長度為size的共享儲存區
2、shmat( )
共享儲存區的附接。從邏輯上將乙個共享儲存區附接到程序的虛擬位址空間上。
系統呼叫格式:
virtaddr=shmat(shmid,addr,flag)
該函式使用標頭檔案如下:
#include
#include
#include
引數定義
char *shmat(shmid,addr,flag);
int shmid,flag;
char * addr;
其中,shmid是共享儲存區的識別符號;addr是使用者給定的,將共享儲存區附接到程序的虛位址空間;flag規定共享儲存區的讀、寫許可權,以及系統是否應對使用者規定的位址做捨入操作。其值為shm_rdonly時,表示只能讀;其值為0時,表示可讀、可寫;其值為shm_rnd(取整)時,表示作業系統在必要時捨去這個位址。該系統呼叫的返回值是共享儲存區所附接到的程序虛位址viraddr。
3、shmdt( )
把乙個共享儲存區從指定程序的虛位址空間斷開。
系統呼叫格式:
shmdt(addr)
該函式使用標頭檔案如下:
#include
#include
#include
引數定義
int shmdt(addr);
char addr;
其中,addr是要斷開連線的虛位址,亦即以前由連線的系統呼叫shmat( )所返回的虛位址。呼叫成功時,返回0值,呼叫不成功,返回-1。
4、shmctl( )
共享儲存區的控制,對其狀態資訊進行讀取和修改。
系統呼叫格式:
shmctl(shmid,cmd,buf)
該函式使用標頭檔案如下:
#include
#include
#include
引數定義
int shmctl(shmid,cmd,buf);
int shmid,cmd;
struct shmid_ds *buf;
其中,buf是使用者緩衝區位址,cmd是操作命令。命令可分為多種型別:
(1)用於查詢有關共享儲存區的情況。如其長度、當前連線的程序數、共享區的建立者識別符號等;
(2)用於設定或改變共享儲存區的屬性。如共享儲存區的許可權、當前連線的程序計數等;
(3)對共享儲存區的加鎖和解鎖命令;
(4)刪除共享儲存區識別符號等。
上述的查詢是將shmid所指示的資料結構中的有關成員,放入所指示的緩衝區中;而設定是用由buf所指示的緩衝區內容來設定由shmid所指示的資料結構中的相應成員。
三、參考程式
#include
#include
#include
#define shmkey 75
int shmid,i; int *addr;
void client( )
exit(0);
}void server( )
while (*addr);
shmctl(shmid,ipc_rmid,0); /*撤消共享儲存區,歸還資源*/
exit(0);
}main( )
四、程式說明
1、為了便於操作和觀察結果,用乙個程式作為「引子「,先後fork()兩個子程序,server和client,進行通訊。
2、server端建立乙個key為75的共享區,並將第乙個位元組置為-1,作為資料空的標誌。等待其他程序發來的訊息。當該位元組的值發生變化時,表示收到了資訊,進行處理。然後再次把它的值設為-1,如果遇到的值為0,則視為為結束訊號,取消該佇列,並退出server。server每接收到一次資料後顯示「(server)received」。
3、client端建立乙個key為75的共享區,當共享取得第乙個位元組為-1時,server端空閒,可傳送請求。client隨即填入9到0。期間等待 server 端的再次空閒。進行完這些操作後,client退出。client每傳送一次資料後顯示「(client)sent」。
4、父程序在server和client均退出後結束。
五、執行結果
和預想的完全一樣。但在執行過程中,發現每當client傳送一次資料後,server要等待大約0.1秒才有響應。同樣,之後client又需要等待大約0.1秒才傳送下乙個資料。
六、程式分析
出現上述應答延遲的現象是程式設計的問題。當client端傳送了資料後,並沒有任何措施通知server端資料已經發出,需要由client的查詢才能感知。此時,client端並沒有放棄系統的控制權,仍然占用cpu的時間片。只有當系統進行排程時,切換到了server程序,再進行應答。這個問題,也同樣存在於server端到client的應答過程中。
七、思考題
1、比較兩種訊息通訊機制中資料傳輸的時間
由於兩種機制實現的機理和用處都不一樣,難以直接進行時間上的比較。如果比較其效能,應更加全面的分析。
(1)訊息佇列的建立比共享區的設立消耗的資源少。前者只是乙個軟體上設定的問題,後者需要對硬體的操作,實現記憶體的映像,當然控制起來比前者複雜。如果每次都重新進行佇列或共享的建立,共享區的設立沒有什麼優勢。
(2)當訊息佇列和共享區建立好後,共享區的資料傳輸,受到了系統硬體的支援,不耗費多餘的資源;而訊息傳遞,由軟體進行控制和實現,需要消耗一定的cpu的資源。從這個意義上講,共享區更適合頻繁和大量的資料傳輸。
(3)訊息的傳遞,自身就帶有同步的控制。當等到訊息的時候,程序進入睡眠狀態,不再消耗cpu資源。而共享佇列如果不借助其他機制進行同步,接收資料的一方必須進行不斷的查詢,白白浪費了大量的cpu資源。可見,訊息方式的使用更加靈活。
六 Linux 共享儲存
include include int shmget key t key,size t size,int shm 功能 得到乙個共享記憶體識別符號或建立乙個共享記憶體物件並返回共享記憶體識別符號 引數 key0 ipc private 會建立新共享記憶體物件 一般應用于父程序和子程序之間 大於0的 ...
程序間通訊 共享儲存
一 什麼是共享儲存 共享儲存允許兩個或更多程序共享一給定的儲存區。因為資料不需要在程序a和程序b之間複製,所以共享儲存是最快的一種ipc。那麼使用共享儲存需要注意的問題是什麼呢?因為是多個程序訪問乙個共同的儲存區,所以需要注意的問題就是多個程序如何實現對同一儲存區實現同步訪問。若程序a正在將資料放入...
15 9 程序間通訊 共享儲存
因為資料不需要在客戶程序和伺服器程序之間複製,所以共享儲存是最快的一種ipc。使用共享儲存時要掌握的唯一竅門是多個程序之間對一給定儲存區的同步訪問。通常,訊號量或記錄鎖被用來實現對共享儲存訪問的同步。返回值 若成功則返回指向共享儲存的指標,若出錯則返回 1 shmget獲得乙個共享儲存識別符號。si...