進程的消息通信-帶答案版_第1頁
進程的消息通信-帶答案版_第2頁
進程的消息通信-帶答案版_第3頁
進程的消息通信-帶答案版_第4頁
進程的消息通信-帶答案版_第5頁
已閱讀5頁,還剩6頁未讀 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

1、實驗二 進程管理2.2 進程的消息通信1.實驗?zāi)康?1) 加深對進程通信的理解,理解進程消息傳遞機制。(2) 掌握進程通信相關(guān)系統(tǒng)調(diào)用。(3) 理解系統(tǒng)調(diào)用和用戶命令的區(qū)別。2.實驗類型:驗證型3.實驗學(xué)時:24.實驗原理和知識點(1) 實驗原理:消息通信機制允許進程之間大批量交換數(shù)據(jù)。消息通信機制是以消息隊列為基礎(chǔ)的,消息隊列是消息的鏈表。發(fā)送進程將消息掛入接收進程的消息隊列,接收進程從消息隊列中接收消息。消息隊列有一個消息描述符。對消息隊列的操作是通過描述符進行的。任何進程,只要有訪問權(quán)并且知道描述符,就可以訪問消息隊列。每個消息包括一個正長整型的類型字段,和一個非負長度的數(shù)據(jù)。進程讀或?qū)?/p>

2、消息時,要給出消息的類型。若隊列中使用的消息類型為0,則讀取隊列中的第一個消息。(2) 知識點:消息、消息隊列 5.實驗環(huán)境(硬件環(huán)境、軟件環(huán)境):(1)硬件環(huán)境:Intel Pentium III 以上CPU,128MB以上內(nèi)存,2GB以上硬盤(2)軟件環(huán)境:linux操作系統(tǒng)。6. 預(yù)備知識(1) msgget()系統(tǒng)調(diào)用:頭文件 #include <sys/msg.h>函數(shù)原型 int msgget(key_t key, int flag);功能:創(chuàng)建消息隊列,或返回與key對應(yīng)的隊列描述符。成功返回消息描述符,失敗則返回-1。參數(shù):key是通信雙方約定的隊列關(guān)鍵字,為長整型

3、數(shù)。flag是訪問控制命令,它的低9位為訪問權(quán)限(代表用戶、組用戶、其他用戶的讀、寫、執(zhí)行訪問權(quán)),其它位為隊列建立方式。(例:rwxrwx-:111111000)(2) msgsnd()系統(tǒng)調(diào)用:頭文件 #include <sys/msg.h>函數(shù)原型 int msgsnd(int id, struct msgbuf *msgp,int size,int flag);功能:發(fā)送一個消息。成功返回0,失敗返回-1。參數(shù):id是隊列描述符。msgp是用戶定義的緩沖區(qū)。size是消息長度。flag是操作行為,若(flag&IPC_NOWAIT)為真,調(diào)用進程立即返回;若(fla

4、g&IPC_NOWAIT)為假,調(diào)用進程阻塞,直到消息被發(fā)送出去或隊列描述符被刪除或收到中斷信號為止。 緩沖區(qū)結(jié)構(gòu)定義如下:struct msgbuf long mtype; char mtextn; ;(3) msgrcv()系統(tǒng)調(diào)用:頭文件 #include <sys/msg.h>函數(shù)原型 int msgrcv(int id, struct msgbuf *msgp, int size,int type,int flag);功能:接收一個消息。成功返回消息正文長度,失敗返回-1。參數(shù):id是隊列描述符。msgp是用戶定義的緩沖區(qū)。size是要接收的消息長度。type是消

5、息類型,若type 為0則接收隊列中的第一個消息,若type為正則接收類型為type的第一個消息。flag是操作行為,若(flag&IPC_NOWAIT)為真,調(diào)用進程立即返回。若(flag&IPC_NOWAIT)為假,調(diào)用進程睡眠,直到接收到消息為止。(4) msgctl()系統(tǒng)調(diào)用:頭文件 #include <sys/msg.h>函數(shù)原型 int msgctl(int id, int cmd, struct msgid_ds *buf);功能:查詢消息隊列描述符狀態(tài),或設(shè)置描述符狀態(tài),或刪除描述符。成功返回0,失敗返回-1。參數(shù):id是隊列描述符。cmd是命令類

6、型,若cmd為IPC_STAT,隊列id的消息隊列頭結(jié)構(gòu)讀入buf中;若cmd為IPC_SET,把buf所指向的信息復(fù)制到id 的消息隊列頭結(jié)構(gòu)中。若cmd為IPC_RMID,刪除id的消息隊列。Buf為消息隊列頭結(jié)構(gòu)msgid_ds指針。(linux IPC7.實驗內(nèi)容及步驟:(1)任務(wù)描述:使用系統(tǒng)調(diào)用msgget()、msgsnd()、msgrcv()、msgctl(),編寫消息發(fā)送和接收程序。要求消息的長度為1KB。(2)程序設(shè)計過程:先定義消息結(jié)構(gòu),struct msgbuf long mtype; char mtextn; ;用這個結(jié)構(gòu)定義消息緩沖全局變量msg。定義消息隊列描述符

7、msgqid。約定隊列關(guān)鍵字為75。創(chuàng)建兩個子進程client和server。Client使用msgget()創(chuàng)建消息隊列,使用msgsnd()發(fā)送10條消息。Server使用msgget()獲取消息隊列描述符,然后用msgrcv()接收消息,完畢后刪除隊列描述符。為了清楚地顯示Client發(fā)送的是哪條消息,每發(fā)送一條消息,打印消息號(消息類型),Sever每收到一條消息,也打印消息類型。設(shè)計收發(fā)方式。Client每發(fā)送一條,Sever就接收一條。/* 收發(fā)方式:Client()每發(fā)送一條消息,Server()就接收一條 */* 此方法不能保證一定能同步。對于不同速度的機器,如果沒有其他耗時的

8、進程,可以調(diào)整sleep的時間值而獲得同步。*/msg.c#include <stdio.h>#include <sys/types.h>#include <sys/msg.h>#include <sys/ipc.h>#define MSGKEY 75 /* 通信雙方約定的隊列關(guān)鍵字*/struct msgform /* 消息結(jié)構(gòu) */ long mtype; /* 消息類型 */char mtext1030; /* 消息正文 */msg;int msgqid; /* 消息隊列描述符 */void Client() int i; /* 局部變量i

9、,消息類型(表示第幾條消息)*/ msgqid=msgget(MSGKEY,0777); /* 創(chuàng)建消息隊列, 訪問權(quán)限為777 */ for(i=10;i>=1;i-) msg.mtype=i; /* 指定消息類型 */ printf("(client %d) sent.n",i); /* 打印消息類型 */ msgsnd(msgqid,&msg,1024,0); /* 發(fā)送消息msg到msgqid消息隊列,可以先把消息正文放到msg.mtext中*/ sleep(1);/*使進程掛起1秒。等待接收進程接收。比較加上這一句和不加這一句的結(jié)果 */ exit(

10、0);void Server() /* 獲得關(guān)鍵字對應(yīng)的消息隊列描述符 */msgqid=msgget(MSGKEY,0777|IPC_CREAT); do msgrcv(msgqid,&msg,1030,0,0); /* 從msgqid隊列接收消息msg */ printf("(server %d)received.n",msg.mtype); /* 打印消息類型 */ while(msg.mtype!=1); /* 消息類型為1時,釋放隊列*/ msgctl(msgqid,IPC_RMID,0); /* 刪除消息隊列 */ exit(0);void main()

11、 int i; while(i=fork()=-1); /* 創(chuàng)建子進程;如果創(chuàng)建失敗,執(zhí)行空語句 */ if(!i) Server(); /* 如果i=0,在子進程中,運行Server */ else /* 否則,在父進程中*/ while(i=fork()=-1); /* 繼續(xù)創(chuàng)建子進程 */ if(!i) Client(); /* 如果i=0,在子進程中,運行Client */ wait(0); /* 等待子進程結(jié)束 */ wait(0); /* 等待子進程結(jié)束 */注:IPC進程間通信(Inter-Process Communication)就是指多個進程之間相互通信,交換信息的方法。

12、(3)上機操作創(chuàng)建 msg.c 源文件,編譯 gcc o msg msg.c,運行 ./msg觀察屏幕,記錄結(jié)果。 簡答:程序中有,sleep(1);/*使進程掛起1秒。等待接收進程接收。比較加上這一句和不加這一句的結(jié)果 */,試分析為什么會有這樣的運行結(jié)果差異。(4)課堂練習(xí)(1)修改上述程序,讓Client向Server發(fā)送一個字符串“The message here is just a joke.”。Server收到消息后打印出來。參考答案:/msg2.c#include <stdio.h>#include <sys/types.h>#include <sy

13、s/msg.h>#include <sys/ipc.h>#define MSGKEY 75 /* 通信雙方約定的隊列關(guān)鍵字*/struct msgform /* 消息結(jié)構(gòu) */ long mtype; /* 消息類型 */char mtext1024; /* 消息正文 */msg;int msgqid; /* 消息隊列描述符 */void Client() msg.mtype=1; strcpy(msg.mtext,"The message here is just a joke."); msgqid=msgget(MSGKEY,0777); /* 創(chuàng)建消

14、息隊列, 訪問權(quán)限為777 */ /* 指定消息類型 */ printf("(client 1) sent.n"); /* 打印消息類型 */ msgsnd(msgqid,&msg,strlen(msg.mtext),0); /* 發(fā)送消息msg到msgqid消息隊列,可以先把消息正文放到msg.mtext中,strlen(msg.mtext)*/ exit(0);void Server() /* 獲得關(guān)鍵字對應(yīng)的消息隊列描述符 */msgqid=msgget(MSGKEY,0777|IPC_CREAT);msgrcv(msgqid,&msg,1024,0,

15、0); /* 從msgqid隊列接收消息msg */ printf("(server 1)received.n"); /* 打印消息類型 */ printf("%sn",msg.mtext); /* 消息類型為1時,釋放隊列*/ msgctl(msgqid,IPC_RMID,0); /* 刪除消息隊列 */ exit(0);void main() int i; while(i=fork()=-1); /* 創(chuàng)建子進程 */ if(!i) Server(); /* 子進程Server */ else while(i=fork()=-1); /* 創(chuàng)建子進程

16、 */ if(!i) Client(); /* 子進程Client */ wait(0); /* 等待子進程結(jié)束 */ wait(0); /* 等待子進程結(jié)束 */(5)思考:1、進程的消息傳遞機制和全局變量是一個概念嗎?消息是通過全局變量進行傳遞的嗎?/msg2.c#include <stdio.h>#include <sys/types.h>#include <sys/msg.h>#include <sys/ipc.h>#define MSGKEY 75 /* 通信雙方約定的隊列關(guān)鍵字*/struct msgform /* 消息結(jié)構(gòu) */ l

17、ong mtype; /* 消息類型 */char mtext1024; /* 消息正文 */msg;int msgqid; /* 消息隊列描述符 */void Client() printf("star copyn"); strcpy(msg.mtext,"The message here is just a joke."); printf("end copyn"); exit(0);void Server() sleep(1); printf("star displayn"); printf("don

18、e!%sn",msg.mtext); printf("end copyn"); exit(0);void main() int i; while(i=fork()=-1); /* 創(chuàng)建子進程 */ if(!i) Server(); /* 子進程Server */ else while(i=fork()=-1); /* 創(chuàng)建子進程 */ if(!i) Client(); /* 子進程Client */ wait(0); /* 等待子進程結(jié)束 */ wait(0); /* 等待子進程結(jié)束 */1. 在client里面改變了msg.mtext,但是server里面pri

19、ntf出來卻什么也沒有,說明全局變量不可在進程間傳遞信息。/msg2.c#include <stdio.h>#include <sys/types.h>#include <sys/msg.h>#include <sys/ipc.h>#define MSGKEY 75 /* 通信雙方約定的隊列關(guān)鍵字*/struct msgform /* 消息結(jié)構(gòu) */ long mtype; /* 消息類型 */char mtext1024; /* 消息正文 */msg;int msgqid; /* 消息隊列描述符 */void Client() sleep(1)

20、; printf("client running!n"); exit(0);void Server() sleep(2); printf("star displayn"); printf("done!%sn",msg.mtext); printf("end copyn"); exit(0);void main() printf("star copyn"); strcpy(msg.mtext,"The message here is just a joke."); printf

21、("end copyn"); int i; while(i=fork()=-1); /* 創(chuàng)建子進程 */ if(!i) Server(); /* 子進程Server */ else while(i=fork()=-1); /* 創(chuàng)建子進程 */ if(!i) Client(); /* 子進程Client */ wait(0); /* 等待子進程結(jié)束 */ wait(0); /* 等待子進程結(jié)束 */2. 在主函數(shù)里面改變?nèi)肿兞渴强梢詡鬟f消息的,因為這是父進程,server是子進程,子進程繼承父進程的全部代碼和資源。 3.換個位置又不行了哦,想想是為什么!有沒有暈了呢!/

22、msg2.c#include <stdio.h>#include <sys/types.h>#include <sys/msg.h>#include <sys/ipc.h>#define MSGKEY 75 /* 通信雙方約定的隊列關(guān)鍵字*/struct msgform /* 消息結(jié)構(gòu) */ long mtype; /* 消息類型 */char mtext1024; /* 消息正文 */msg;int msgqid; /* 消息隊列描述符 */void Client() sleep(1); printf("client running!

23、n"); exit(0);void Server() sleep(2); printf("star displayn"); printf("done!%sn",msg.mtext); printf("end copyn"); exit(0);void main() int i; while(i=fork()=-1); /* 創(chuàng)建子進程 */ if(!i) Server(); /* 子進程Server */ else while(i=fork()=-1); /* 創(chuàng)建子進程 */ if(!i) printf("sta

24、r copyn"); strcpy(msg.mtext,"The message here is just a joke."); printf("end copyn"); Client(); /* 子進程Client */ wait(0); /* 等待子進程結(jié)束 */ wait(0); /* 等待子進程結(jié)束 */簡單的說,不同的進程使用的內(nèi)存空間是不共用的,全局變量只是在同一個進程所占用的內(nèi)存空間中是全局變量,而其他的進程空間是根本看不到這個變量的。父子進程不共享數(shù)據(jù)空間、堆、和棧。所以不存在共享全局變量。進程間只能IPC。2、修改上述程序,讓

25、Client向Server發(fā)送兩個字符串“The message here is just a joke.”。Server收到消息后打印出來。效果圖如下。/msg2.c#include <stdio.h>#include <sys/types.h>#include <sys/msg.h>#include <sys/ipc.h>#define MSGKEY 75 /* 通信雙方約定的隊列關(guān)鍵字*/struct msgform /* 消息結(jié)構(gòu) */ long mtype; /* 消息類型 */char mtext1024; /* 消息正文 */msg

26、;int msgqid; /* 消息隊列描述符 */void Client() msgqid=msgget(MSGKEY,0777); /* 創(chuàng)建消息隊列, 訪問權(quán)限為777 */ /* 指定消息類型 */消息1發(fā)送msg.mtype=1; strcpy(msg.mtext,"Thank you."); printf("(client 1) sent.n"); /* 打印消息類型 */ msgsnd(msgqid,&msg,strlen(msg.mtext),0); /* 發(fā)送消息msg到msgqid消息隊列,可以先把消息正文放到msg.mtext中,strlen(msg.mtext)*/消息2發(fā)送msg.mtype=2; strcpy(msg.mtext,&quo

溫馨提示

  • 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)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論