操作系統(tǒng)實(shí)驗(yàn) 消息的發(fā)送與接收_第1頁
操作系統(tǒng)實(shí)驗(yàn) 消息的發(fā)送與接收_第2頁
操作系統(tǒng)實(shí)驗(yàn) 消息的發(fā)送與接收_第3頁
操作系統(tǒng)實(shí)驗(yàn) 消息的發(fā)送與接收_第4頁
操作系統(tǒng)實(shí)驗(yàn) 消息的發(fā)送與接收_第5頁
已閱讀5頁,還剩2頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡介

1、MSG一、實(shí)驗(yàn)?zāi)康?、了解什么是消息 2、熟悉消息傳送的機(jī)理。二、實(shí)驗(yàn)內(nèi)容   消息的創(chuàng)建、發(fā)送和接收。使用系統(tǒng)調(diào)用msgget( ),msgsnd( ),msgrev( ),及msgctl( )編制一長度為k的消息發(fā)送和接收的程序三、實(shí)驗(yàn)內(nèi)容指導(dǎo)提示(一)、什么是消息消息(message)是一個(gè)格式化的可變長的信息單元。消息機(jī)制允許由一個(gè)進(jìn)程給其它任意的進(jìn)程發(fā)送一個(gè)消息。當(dāng)一個(gè)進(jìn)程收到多個(gè)消息時(shí),可將它們排成一個(gè)消息隊(duì)列。消息使用二種重要的數(shù)據(jù)結(jié)構(gòu):一是消息首部,其中記錄了一些與消息有關(guān)的信息,如消息數(shù)據(jù)的字節(jié)數(shù);二個(gè)消息隊(duì)列頭表,其每一表項(xiàng)是作為一個(gè)消息隊(duì)列的

2、消息頭,記錄了消息隊(duì)列的有關(guān)信息。1、消息機(jī)制的數(shù)據(jù)結(jié)構(gòu)(1)消息首部記錄一些與消息有關(guān)的信息,如消息的類型、大小、指向消息數(shù)據(jù)區(qū)的指針、消息隊(duì)列的鏈接指針等。(2)消息隊(duì)列頭表其每一項(xiàng)作為一個(gè)消息隊(duì)列的消息頭,記錄了消息隊(duì)列的有關(guān)信息如指向消息隊(duì)列中第一個(gè)消息和指向最后一個(gè)消息的指針、隊(duì)列中消息的數(shù)目、隊(duì)列中消息數(shù)據(jù)的總字節(jié)數(shù)、隊(duì)列所允許消息數(shù)據(jù)的最大字節(jié)總數(shù),還有最近一次執(zhí)行發(fā)送操作的進(jìn)程標(biāo)識符和時(shí)間、最近一次執(zhí)行接收操作的進(jìn)程標(biāo)識符和時(shí)間等。2、消息隊(duì)列的描述符UNIX中,每一個(gè)消息隊(duì)列都有一個(gè)稱為關(guān)鍵字(key)的名字,是由用戶指定的;消息隊(duì)列有一消息隊(duì)列描述符,其作用與用戶文件描述符

3、一樣,也是為了方便用戶和系統(tǒng)對消息隊(duì)列的訪問。(二)、涉及的系統(tǒng)調(diào)用1. msgget( )創(chuàng)建一個(gè)消息,獲得一個(gè)消息的描述符。核心將搜索消息隊(duì)列頭表,確定是否有指定名字的消息隊(duì)列。若無,核心將分配一新的消息隊(duì)列頭,并對它進(jìn)行初始化,然后給用戶返回一個(gè)消息隊(duì)列描述符,否則它只是檢查消息隊(duì)列的許可權(quán)便返回。系統(tǒng)調(diào)用格式:msgqid=msgget(key,flag)該函數(shù)使用頭文件如下:#include<sys/types.h>#include<sys/ipc.h>#include<sys/msg.h>參數(shù)定義int msgget(key,flag)key_t

4、 key;int flag;其中:key是用戶指定的消息隊(duì)列的名字;flag是用戶設(shè)置的標(biāo)志和訪問方式。如 IPC_CREAT |0400 是否該隊(duì)列已被創(chuàng)建。無則創(chuàng)建,是則打開;IPC_EXCL |0400 是否該隊(duì)列的創(chuàng)建應(yīng)是互斥的。msgqid 是該系統(tǒng)調(diào)用返回的描述符,失敗則返回-1。2. msgsnd()發(fā)送一消息。向指定的消息隊(duì)列發(fā)送一個(gè)消息,并將該消息鏈接到該消息隊(duì)列的尾部。系統(tǒng)調(diào)用格式: msgsnd(msgqid,msgp,size,flag)該函數(shù)使用頭文件如下:#include <sys/types.h>#include <sys/ipc.h>#i

5、nclude <sys/msg.h>參數(shù)定義:int msgsnd(msgqid,msgp,size,flag)I int msgqid,size,flag;struct msgbuf * msgp;其中msgqid是返回消息隊(duì)列的描述符;msgp是指向用戶消息緩沖區(qū)的一個(gè)結(jié)構(gòu)體指針。緩沖區(qū)中包括消息類型和消息正文,即 long mtype; /*消息類型*/ char mtext ; /*消息的文本*/ size指示由msgp指向的數(shù)據(jù)結(jié)構(gòu)中字符數(shù)組的長度;即消息的長度。這個(gè)數(shù)組的最大值由MSG-MAX( )系統(tǒng)可調(diào)用參數(shù)來確定。flag規(guī)定當(dāng)核心用盡內(nèi)部緩沖空間時(shí)應(yīng)執(zhí)行的動作:

6、進(jìn)程是等待,還是立即返回。若在標(biāo)志flag中未設(shè)置IPC_NOWAIT位,則當(dāng)該消息隊(duì)列中的字節(jié)數(shù)超過最大值時(shí),或系統(tǒng)范圍的消息數(shù)超過某一最大值時(shí),調(diào)用msgsnd進(jìn)程睡眠。若是設(shè)置IPC_NOWAIT,則在此情況下,msgsnd立即返回。對于msgsnd( ),核心須完成以下工作:(1)對消息隊(duì)列的描述符和許可權(quán)及消息長度等進(jìn)行檢查。若合法才繼續(xù)執(zhí)行,否則返回;(2)核心為消息分配消息數(shù)據(jù)區(qū)。將用戶消息緩沖區(qū)中的消息正文,拷貝到消息數(shù)據(jù)區(qū);(3)分配消息首部,并將它鏈入消息隊(duì)列的末尾。在消息首部中須填寫消息類型、消息大小和指向消息數(shù)據(jù)區(qū)的指針等數(shù)據(jù);(4)修改消息隊(duì)列頭中的數(shù)據(jù),如隊(duì)列中的消

7、息數(shù)、字節(jié)總數(shù)等。最后,喚醒等待消息的進(jìn)程。3. msgrcv( )接受一消息。從指定的消息隊(duì)列中接收指定類型的消息。系統(tǒng)調(diào)用格式: msgrcv(msgqid,msgp,size,type,flag)本函數(shù)使用的頭文件如下: #include <sys/types.h> #include <sys/ipc.h> #include <sys/msg.h>參數(shù)定義: int msgrcv(msgqid,msgp,size,type,flag) int msgqid,size,flag; struct msgbuf *msgp; long type;其中,msg

8、qid,msgp,size,flag與msgsnd中的對應(yīng)參數(shù)相似,type是規(guī)定要讀的消息類型,flag規(guī)定倘若該隊(duì)列無消息,核心應(yīng)做的操作。如此時(shí)設(shè)置了IPC_NOWAIT標(biāo)志,則立即返回,若在flag中設(shè)置了MS_NOERROR,且所接收的消息大于size,則核心截?cái)嗨邮盏南?。對于msgrcv系統(tǒng)調(diào)用,核心須完成下述工作:(1)對消息隊(duì)列的描述符和許可權(quán)等進(jìn)行檢查。若合法,就往下執(zhí)行;否則返回;(2)根據(jù)type的不同分成三種情況處理:type=0,接收該隊(duì)列的第一個(gè)消息,并將它返回給調(diào)用者;type為正整數(shù),接收類型type的第一個(gè)消息;type為負(fù)整數(shù),接收小于等于type絕對值

9、的最低類型的第一個(gè)消息。(3)當(dāng)所返回消息大小等于或小于用戶的請求時(shí),核心便將消息正文拷貝到用戶區(qū),并從消息隊(duì)列中刪除此消息,然后喚醒睡眠的發(fā)送進(jìn)程。但如果消息長度比用戶要求的大時(shí),則做出錯(cuò)返回。4. msgctl( )消息隊(duì)列的操縱。讀取消息隊(duì)列的狀態(tài)信息并進(jìn)行修改,如查詢消息隊(duì)列描述符、修改它的許可權(quán)及刪除該隊(duì)列等。系統(tǒng)調(diào)用格式: msgctl(msgqid,cmd,buf);本函數(shù)使用的頭文件如下: #include <sys/types.h> #include <sys/ipc.h> #include <sys/msg.h>參數(shù)定義: int msg

10、ctl(msgqid,cmd,buf); int msgqid,cmd; struct msgqid_ds *buf;其中,函數(shù)調(diào)用成功時(shí)返回0,不成功則返回-1。buf是用戶緩沖區(qū)地址,供用戶存放控制參數(shù)和查詢結(jié)果;cmd是規(guī)定的命令。命令可分三類:(1)IPC_STAT。查詢有關(guān)消息隊(duì)列情況的命令。如查詢隊(duì)列中的消息數(shù)目、隊(duì)列中的最大字節(jié)數(shù)、最后一個(gè)發(fā)送消息的進(jìn)程標(biāo)識符、發(fā)送時(shí)間等;(2)IPC_SET。按buf指向的結(jié)構(gòu)中的值,設(shè)置和改變有關(guān)消息隊(duì)列屬性的命令。如改變消息隊(duì)列的用戶標(biāo)識符、消息隊(duì)列的許可權(quán)等;(3)IPC_RMID。消除消息隊(duì)列的標(biāo)識符。msgqid_ds 結(jié)構(gòu)定義如下:

11、struct msgqid_ds struct ipc_perm msg_perm; /*許可權(quán)結(jié)構(gòu)*/ short pad17; /*由系統(tǒng)使用*/ ushort msg_qnum; /*隊(duì)列上消息數(shù)*/ ushort msg_qbytes; /*隊(duì)列上最大字節(jié)數(shù)*/ ushort msg_lspid; /*最后發(fā)送消息的PID*/ ushort msg_lrpid; /*最后接收消息的PID*/ time_t msg_stime; /*最后發(fā)送消息的時(shí)間*/ time_t msg_rtime; /*最后接收消息的時(shí)間*/ time_t msg_ctime; /*最后更改時(shí)間*/ ;stru

12、ct ipc_perm ushort uid; /*當(dāng)前用戶*/ ushort gid; /*當(dāng)前進(jìn)程組*/ ushort cuid; /*創(chuàng)建用戶*/ ushort cgid; /*創(chuàng)建進(jìn)程組*/ ushort mode; /*存取許可權(quán)*/ short pid1; long pad2; /*由系統(tǒng)使用*/ (三)、參考程序1、client.c#include <sys/types.h>#include <sys/msg.h>#include <sys/ipc.h>#define MSGKEY 75struct msgform long mtype; ch

13、ar mtext1000;msg;int msgqid;void client() int i;msgqid=msgget(MSGKEY,0777); /*打開75#消息隊(duì)列*/for(i=10;i>=1;i-) msg.mtype=i;printf(“(client)sentn”);msgsnd(msgqid,&msg,1024,0); /*發(fā)送消息*/exit(0);main( ) client( );2、server.c#include <sys/types.h>#include <sys/msg.h>#include <sys/ipc.h&g

14、t;#define MSGKEY 75struct msgform long mtype; char mtext1000;msg;int msgqid;void server( ) msgqid=msgget(MSGKEY,0777|IPC_CREAT); /*創(chuàng)建75#消息隊(duì)列*/do msgrcv(msgqid,&msg,1030,0,0); /*接收消息*/ printf(“(server)receivedn”);while(msg.mtype!=1);msgctl(msgqid,IPC_RMID,0); /*刪除消息隊(duì)列,歸還資源*/exit(0);main( ) server

15、( );(四)、程序說明1、為了便于操作和觀察結(jié)果,編制二個(gè)程序client.c和server.c,分別用于消息的發(fā)送與接收。2、server建立一個(gè) Key 為75的消息隊(duì)列,等待其它進(jìn)程發(fā)來的消息。當(dāng)遇到類型為1的消息,則作為結(jié)束信號,取消該隊(duì)列,并退出server。server每接收到一個(gè)消息后顯示一句“(server)received?!?、client使用 key為75的消息隊(duì)列,先后發(fā)送類型從10到1的消息,然后退出。最后一個(gè)消息,即是 server端需要的結(jié)束信號。client 每發(fā)送一條消息后顯示一句 “(client)sent”。4、注意: 二個(gè)程序分別編輯、編譯為clien

16、t與server。執(zhí)行:./server&ipcs -q./client。(五)、運(yùn)行結(jié)果從理想的結(jié)果來說,應(yīng)當(dāng)是每當(dāng)client發(fā)送一個(gè)消息后,server接收該消息,client再發(fā)送下一條。也就是說“(client)sent”和 “(server)received”的字樣應(yīng)該在屏幕上交替出現(xiàn)。實(shí)際的結(jié)果大多是,先由client發(fā)送了兩條消息,然后server接收一條消息。此后client 、server交替發(fā)送和接收消息。最后server一次接收兩條消息。client 和server 分別發(fā)送和接收了10條消息,與預(yù)期設(shè)想一致。(六)、思考message的傳送和控制并不保證完全同

17、步,當(dāng)一個(gè)程序不在激活狀態(tài)的時(shí)候,它完全可能繼續(xù)睡眠,造成了上面的現(xiàn)象,在多次send message 后才recieve message。這一點(diǎn)有助于理解消息傳送的實(shí)現(xiàn)機(jī)理。【附加:共享存儲區(qū)的創(chuàng)建,附接和斷接來實(shí)現(xiàn)進(jìn)程通信留給有時(shí)間的同學(xué)看<任務(wù)> 使用系統(tǒng)調(diào)用shmget(),sgmat(),smgdt(),shmctl()編制一個(gè)與上述功能相同的程序.<程序設(shè)計(jì)> (1)為了便于操作 和觀察結(jié)果,用一個(gè) 程序?yàn)椤耙印?,先后fork( )兩個(gè)子進(jìn)程,SERVER 和 CLIENT,進(jìn)行通信。 (2)SERVER端建立一個(gè)KEY為75的共享區(qū),并將第一個(gè)字節(jié)置為-

18、1.作為數(shù)據(jù)空的標(biāo)志.等待其他進(jìn)程發(fā)來的消息.當(dāng)該字節(jié)的值發(fā)生變化時(shí),表示收到了該消息,進(jìn)行處理.然后再次把它的值設(shè)為-1.如果遇到的值為0,則視為結(jié)束信號,取消該隊(duì)列,并退出SERVER.SERVER每接收到一次數(shù)據(jù)后顯示”(server)received”. (3)CLIENT端建立一個(gè)為75的共享區(qū),當(dāng)共享取得第一個(gè)字節(jié)為-1時(shí), Server端空閑,可發(fā)送請求. CLIENT 隨即填入9到0.期間等待Server端再次空閑.進(jìn)行完這些操作后, CLIENT 退出. CLIENT每發(fā)送一次數(shù)據(jù)后顯示”(client)sent”. (4)父進(jìn)程在SERVER和CLIENT均退出后結(jié)束.&l

19、t;程序>#include<sys/types.h>#include<sys/msg.h>#include<sys/ipc.h>#define SHMKEY 75 /*定義共享區(qū)關(guān)鍵詞*/int shmid,i;int *addr;void * shmat();/*如果去掉這行,看看運(yùn)行結(jié)果,分析為什么*/ CLIENT()int i;shmid=shmget(SHMKEY,1024, 0777|IPC_CREAT); /*獲取共享區(qū),長度1024,關(guān)鍵詞SHMKEY*/addr=shmat(shmid,0,0); /*共享區(qū)起始地址為addr*/fo

20、r(i=9;i>=0;i-) while(*addr!= -1); printf("(client)sentn"); /*打?。╟lient)sent*/*addr=i; /*把i賦給addr*/exit(0); SERVER() dowhile(*addr = =-1);printf("(server)receivedn%d",*addr); /*服務(wù)進(jìn)程使用共享區(qū)*/if(*addr!=0)*addr=-1; while(*addr); wait(0);shmctl(shmid,IPC_RMID,0); main()shmid=shmget(SHMKEY,1024,0777|IPC_CREAT); /*創(chuàng)建共享區(qū)*/addr=shmat(shmid,0,0); /*共享區(qū)起始地址為addr*/*addr=-1;if(fork() SERVER();el

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論