進(jìn)程的消息通信-帶答案版#嚴(yán)選材料_第1頁
進(jìn)程的消息通信-帶答案版#嚴(yán)選材料_第2頁
進(jìn)程的消息通信-帶答案版#嚴(yán)選材料_第3頁
已閱讀5頁,還剩6頁未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡(jiǎn)介

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

2、消息時(shí),要給出消息的類型。若隊(duì)列中使用的消息類型為0,則讀取隊(duì)列中的第一個(gè)消息。(2) 知識(shí)點(diǎn):消息、消息隊(duì)列 5.實(shí)驗(yàn)環(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ù)備知識(shí)(1) msgget()系統(tǒng)調(diào)用:頭文件 #include 函數(shù)原型 int msgget(key_t key, int flag);功能:創(chuàng)建消息隊(duì)列,或返回與key對(duì)應(yīng)的隊(duì)列描述符。成功返回消息描述符,失敗則返回-1。參數(shù):key是通信雙方約定的隊(duì)列關(guān)鍵字,為長整型數(shù)。flag是訪問控制命令,它的低

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

4、被刪除或收到中斷信號(hào)為止。 緩沖區(qū)結(jié)構(gòu)定義如下:struct msgbuf long mtype; char mtextn; ;(3) msgrcv()系統(tǒng)調(diào)用:頭文件 #include 函數(shù)原型 int msgrcv(int id, struct msgbuf *msgp, int size,int type,int flag);功能:接收一個(gè)消息。成功返回消息正文長度,失敗返回-1。參數(shù):id是隊(duì)列描述符。msgp是用戶定義的緩沖區(qū)。size是要接收的消息長度。type是消息類型,若type 為0則接收隊(duì)列中的第一個(gè)消息,若type為正則接收類型為type的第一個(gè)消息。flag是操作行為,

5、若(flag&IPC_NOWAIT)為真,調(diào)用進(jìn)程立即返回。若(flag&IPC_NOWAIT)為假,調(diào)用進(jìn)程睡眠,直到接收到消息為止。(4) msgctl()系統(tǒng)調(diào)用:頭文件 #include 函數(shù)原型 int msgctl(int id, int cmd, struct msgid_ds *buf);功能:查詢消息隊(duì)列描述符狀態(tài),或設(shè)置描述符狀態(tài),或刪除描述符。成功返回0,失敗返回-1。參數(shù):id是隊(duì)列描述符。cmd是命令類型,若cmd為IPC_STAT,隊(duì)列id的消息隊(duì)列頭結(jié)構(gòu)讀入buf中;若cmd為IPC_SET,把buf所指向的信息復(fù)制到id 的消息隊(duì)列頭結(jié)構(gòu)中。若cmd為IPC_R

6、MID,刪除id的消息隊(duì)列。Buf為消息隊(duì)列頭結(jié)構(gòu)msgid_ds指針。(linux IPC/link?url=NtXNw0BBI7lTg09Gt7Vy_IrwPRP0XyD5n1-s3ZQV-gP7iHN_ndEBOnrA5fYVNOA3wGqnwoahUWnBNkHUeQUrzIdSIsg8uiV0DWlZFHzOn4K)7.實(shí)驗(yàn)內(nèi)容及步驟:(1)任務(wù)描述:使用系統(tǒng)調(diào)用msgget()、msgsnd()、msgrcv()、msgctl(),編寫消息發(fā)送和接收程序。要求消息的長度為1KB。(2)程序設(shè)計(jì)過程:先定義消息結(jié)構(gòu),struct msgbuf

7、 long mtype; char mtextn; ;用這個(gè)結(jié)構(gòu)定義消息緩沖全局變量msg。定義消息隊(duì)列描述符msgqid。約定隊(duì)列關(guān)鍵字為75。創(chuàng)建兩個(gè)子進(jìn)程client和server。Client使用msgget()創(chuàng)建消息隊(duì)列,使用msgsnd()發(fā)送10條消息。Server使用msgget()獲取消息隊(duì)列描述符,然后用msgrcv()接收消息,完畢后刪除隊(duì)列描述符。為了清楚地顯示Client發(fā)送的是哪條消息,每發(fā)送一條消息,打印消息號(hào)(消息類型),Sever每收到一條消息,也打印消息類型。設(shè)計(jì)收發(fā)方式。Client每發(fā)送一條,Sever就接收一條。/* 收發(fā)方式:Client()每發(fā)送

8、一條消息,Server()就接收一條 */* 此方法不能保證一定能同步。對(duì)于不同速度的機(jī)器,如果沒有其他耗時(shí)的進(jìn)程,可以調(diào)整sleep的時(shí)間值而獲得同步。*/msg.c#include #include #include #include #define MSGKEY 75 /* 通信雙方約定的隊(duì)列關(guān)鍵字*/struct msgform /* 消息結(jié)構(gòu) */ long mtype; /* 消息類型 */char mtext1030; /* 消息正文 */msg;int msgqid; /* 消息隊(duì)列描述符 */void Client() int i; /* 局部變量i,消息類型(表示第幾條消息

9、)*/ msgqid=msgget(MSGKEY,0777); /* 創(chuàng)建消息隊(duì)列, 訪問權(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消息隊(duì)列,可以先把消息正文放到msg.mtext中*/ sleep(1);/*使進(jìn)程掛起1秒。等待接收進(jìn)程接收。比較加上這一句和不加這一句的結(jié)果 */ exit(0);void Server() /* 獲得關(guān)鍵字對(duì)應(yīng)的消息隊(duì)列描述

10、符 */msgqid=msgget(MSGKEY,0777|IPC_CREAT); do msgrcv(msgqid,&msg,1030,0,0); /* 從msgqid隊(duì)列接收消息msg */ printf(server %d)received.n,msg.mtype); /* 打印消息類型 */ while(msg.mtype!=1); /* 消息類型為1時(shí),釋放隊(duì)列*/ msgctl(msgqid,IPC_RMID,0); /* 刪除消息隊(duì)列 */ exit(0);void main() int i; while(i=fork()=-1); /* 創(chuàng)建子進(jìn)程;如果創(chuàng)建失敗,執(zhí)行空語句 *

11、/ if(!i) Server(); /* 如果i=0,在子進(jìn)程中,運(yùn)行Server */ else /* 否則,在父進(jìn)程中*/ while(i=fork()=-1); /* 繼續(xù)創(chuàng)建子進(jìn)程 */ if(!i) Client(); /* 如果i=0,在子進(jìn)程中,運(yùn)行Client */ wait(0); /* 等待子進(jìn)程結(jié)束 */ wait(0); /* 等待子進(jìn)程結(jié)束 */注:IPC進(jìn)程間通信(Inter-Process Communication)就是指多個(gè)進(jìn)程之間相互通信,交換信息的方法。/liugf05/archive/2012/07/05/25

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

13、通信雙方約定的隊(duì)列關(guān)鍵字*/struct msgform /* 消息結(jié)構(gòu) */ long mtype; /* 消息類型 */char mtext1024; /* 消息正文 */msg;int msgqid; /* 消息隊(duì)列描述符 */void Client() msg.mtype=1; strcpy(msg.mtext,The message here is just a joke.); msgqid=msgget(MSGKEY,0777); /* 創(chuàng)建消息隊(duì)列, 訪問權(quán)限為777 */ /* 指定消息類型 */ printf(client 1) sent.n); /* 打印消息類型 */ m

14、sgsnd(msgqid,&msg,strlen(msg.mtext),0); /* 發(fā)送消息msg到msgqid消息隊(duì)列,可以先把消息正文放到msg.mtext中,strlen(msg.mtext)*/ exit(0);void Server() /* 獲得關(guān)鍵字對(duì)應(yīng)的消息隊(duì)列描述符 */msgqid=msgget(MSGKEY,0777|IPC_CREAT);msgrcv(msgqid,&msg,1024,0,0); /* 從msgqid隊(duì)列接收消息msg */ printf(server 1)received.n); /* 打印消息類型 */ printf(%sn,msg.mtext);

15、 /* 消息類型為1時(shí),釋放隊(duì)列*/ msgctl(msgqid,IPC_RMID,0); /* 刪除消息隊(duì)列 */ exit(0);void main() int i; while(i=fork()=-1); /* 創(chuàng)建子進(jìn)程 */ if(!i) Server(); /* 子進(jìn)程Server */ else while(i=fork()=-1); /* 創(chuàng)建子進(jìn)程 */ if(!i) Client(); /* 子進(jìn)程Client */ wait(0); /* 等待子進(jìn)程結(jié)束 */ wait(0); /* 等待子進(jìn)程結(jié)束 */(5)思考:1、進(jìn)程的消息傳遞機(jī)制和全局變量是一個(gè)概念嗎?消息是通過

16、全局變量進(jìn)行傳遞的嗎?/msg2.c#include #include #include #include #define MSGKEY 75 /* 通信雙方約定的隊(duì)列關(guān)鍵字*/struct msgform /* 消息結(jié)構(gòu) */ long mtype; /* 消息類型 */char mtext1024; /* 消息正文 */msg;int msgqid; /* 消息隊(duì)列描述符 */void Client() printf(star copyn); strcpy(msg.mtext,The message here is just a joke.); printf(end copyn); exi

17、t(0);void Server() sleep(1); printf(star displayn); printf(done!%sn,msg.mtext); printf(end copyn); exit(0);void main() int i; while(i=fork()=-1); /* 創(chuàng)建子進(jìn)程 */ if(!i) Server(); /* 子進(jìn)程Server */ else while(i=fork()=-1); /* 創(chuàng)建子進(jìn)程 */ if(!i) Client(); /* 子進(jìn)程Client */ wait(0); /* 等待子進(jìn)程結(jié)束 */ wait(0); /* 等待子進(jìn)

18、程結(jié)束 */1. 在client里面改變了msg.mtext,但是server里面printf出來卻什么也沒有,說明全局變量不可在進(jìn)程間傳遞信息。/msg2.c#include #include #include #include #define MSGKEY 75 /* 通信雙方約定的隊(duì)列關(guān)鍵字*/struct msgform /* 消息結(jié)構(gòu) */ long mtype; /* 消息類型 */char mtext1024; /* 消息正文 */msg;int msgqid; /* 消息隊(duì)列描述符 */void Client() sleep(1); printf(client running!

19、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(end copyn); int i; while(i=fork()=-1); /* 創(chuàng)建子進(jìn)程 */ if(!i) Server(); /* 子進(jìn)程Server */ else while(

20、i=fork()=-1); /* 創(chuàng)建子進(jìn)程 */ if(!i) Client(); /* 子進(jìn)程Client */ wait(0); /* 等待子進(jìn)程結(jié)束 */ wait(0); /* 等待子進(jìn)程結(jié)束 */2. 在主函數(shù)里面改變?nèi)肿兞渴强梢詡鬟f消息的,因?yàn)檫@是父進(jìn)程,server是子進(jìn)程,子進(jìn)程繼承父進(jìn)程的全部代碼和資源。 3.換個(gè)位置又不行了哦,想想是為什么!有沒有暈了呢!/msg2.c#include #include #include #include #define MSGKEY 75 /* 通信雙方約定的隊(duì)列關(guān)鍵字*/struct msgform /* 消息結(jié)構(gòu) */ long

21、mtype; /* 消息類型 */char mtext1024; /* 消息正文 */msg;int msgqid; /* 消息隊(duì)列描述符 */void Client() sleep(1); 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() int i; while(i=fork()=-1); /* 創(chuàng)建子進(jìn)程 */ if(!i) Server();

22、/* 子進(jìn)程Server */ else while(i=fork()=-1); /* 創(chuàng)建子進(jìn)程 */ if(!i) printf(star copyn); strcpy(msg.mtext,The message here is just a joke.); printf(end copyn); Client(); /* 子進(jìn)程Client */ wait(0); /* 等待子進(jìn)程結(jié)束 */ wait(0); /* 等待子進(jìn)程結(jié)束 */簡(jiǎn)單的說,不同的進(jìn)程使用的內(nèi)存空間是不共用的,全局變量只是在同一個(gè)進(jìn)程所占用的內(nèi)存空間中是全局變量,而其他的進(jìn)程空間是根本看不到這個(gè)變量的。父子進(jìn)程不共享數(shù)

23、據(jù)空間、堆、和棧。所以不存在共享全局變量。進(jìn)程間只能IPC。2、修改上述程序,讓Client向Server發(fā)送兩個(gè)字符串“The message here is just a joke.”。Server收到消息后打印出來。效果圖如下。/msg2.c#include #include #include #include #define MSGKEY 75 /* 通信雙方約定的隊(duì)列關(guān)鍵字*/struct msgform /* 消息結(jié)構(gòu) */ long mtype; /* 消息類型 */char mtext1024; /* 消息正文 */msg;int msgqid; /* 消息隊(duì)列描述符 */void Client() msgqid=msgget(MSGKEY,0777); /* 創(chuàng)建消息隊(duì)列, 訪問權(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消息隊(duì)列,可以先把消息正文放到msg.mtext中,strlen(msg.mtext)*/消息2發(fā)送msg.mtype=2; strcpy(msg.mt

溫馨提示

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

最新文檔

評(píng)論

0/150

提交評(píng)論