




版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
1、實驗二 進程管理2.2 進程的消息通信1.實驗目的(1) 加深對進程通信的理解,理解進程消息傳遞機制。(2) 掌握進程通信相關系統調用。(3) 理解系統調用和用戶命令的區別。2.實驗類型:驗證型3.實驗學時:24.實驗原理和知識點(1) 實驗原理:消息通信機制允許進程之間大批量交換數據。消息通信機制是以消息隊列為基礎的,消息隊列是消息的鏈表。發送進程將消息掛入接收進程的消息隊列,接收進程從消息隊列中接收消息。消息隊列有一個消息描述符。對消息隊列的操作是通過描述符進行的。任何進程,只要有訪問權并且知道描述符,就可以訪問消息隊列。每個消息包括一個正長整型的類型字段,和一個非負長度的數據。進程讀或寫
2、消息時,要給出消息的類型。若隊列中使用的消息類型為0,則讀取隊列中的第一個消息。(2) 知識點:消息、消息隊列 5.實驗環境(硬件環境、軟件環境):(1)硬件環境:Intel Pentium III 以上CPU,128MB以上內存,2GB以上硬盤(2)軟件環境:linux操作系統。6. 預備知識(1) msgget()系統調用:頭文件 #include <sys/msg.h>函數原型 int msgget(key_t key, int flag);功能:創建消息隊列,或返回與key對應的隊列描述符。成功返回消息描述符,失敗則返回-1。參數:key是通信雙方約定的隊列關鍵字,為長整型
3、數。flag是訪問控制命令,它的低9位為訪問權限(代表用戶、組用戶、其他用戶的讀、寫、執行訪問權),其它位為隊列建立方式。(例:rwxrwx-:111111000)(2) msgsnd()系統調用:頭文件 #include <sys/msg.h>函數原型 int msgsnd(int id, struct msgbuf *msgp,int size,int flag);功能:發送一個消息。成功返回0,失敗返回-1。參數:id是隊列描述符。msgp是用戶定義的緩沖區。size是消息長度。flag是操作行為,若(flag&IPC_NOWAIT)為真,調用進程立即返回;若(fla
4、g&IPC_NOWAIT)為假,調用進程阻塞,直到消息被發送出去或隊列描述符被刪除或收到中斷信號為止。 緩沖區結構定義如下:struct msgbuf long mtype; char mtextn; ;(3) msgrcv()系統調用:頭文件 #include <sys/msg.h>函數原型 int msgrcv(int id, struct msgbuf *msgp, int size,int type,int flag);功能:接收一個消息。成功返回消息正文長度,失敗返回-1。參數:id是隊列描述符。msgp是用戶定義的緩沖區。size是要接收的消息長度。type是消
5、息類型,若type 為0則接收隊列中的第一個消息,若type為正則接收類型為type的第一個消息。flag是操作行為,若(flag&IPC_NOWAIT)為真,調用進程立即返回。若(flag&IPC_NOWAIT)為假,調用進程睡眠,直到接收到消息為止。(4) msgctl()系統調用:頭文件 #include <sys/msg.h>函數原型 int msgctl(int id, int cmd, struct msgid_ds *buf);功能:查詢消息隊列描述符狀態,或設置描述符狀態,或刪除描述符。成功返回0,失敗返回-1。參數:id是隊列描述符。cmd是命令類
6、型,若cmd為IPC_STAT,隊列id的消息隊列頭結構讀入buf中;若cmd為IPC_SET,把buf所指向的信息復制到id 的消息隊列頭結構中。若cmd為IPC_RMID,刪除id的消息隊列。Buf為消息隊列頭結構msgid_ds指針。(linux IPC7.實驗內容及步驟:(1)任務描述:使用系統調用msgget()、msgsnd()、msgrcv()、msgctl(),編寫消息發送和接收程序。要求消息的長度為1KB。(2)程序設計過程:先定義消息結構,struct msgbuf long mtype; char mtextn; ;用這個結構定義消息緩沖全局變量msg。定義消息隊列描述符
7、msgqid。約定隊列關鍵字為75。創建兩個子進程client和server。Client使用msgget()創建消息隊列,使用msgsnd()發送10條消息。Server使用msgget()獲取消息隊列描述符,然后用msgrcv()接收消息,完畢后刪除隊列描述符。為了清楚地顯示Client發送的是哪條消息,每發送一條消息,打印消息號(消息類型),Sever每收到一條消息,也打印消息類型。設計收發方式。Client每發送一條,Sever就接收一條。/* 收發方式:Client()每發送一條消息,Server()就接收一條 */* 此方法不能保證一定能同步。對于不同速度的機器,如果沒有其他耗時的
8、進程,可以調整sleep的時間值而獲得同步。*/msg.c#include <stdio.h>#include <sys/types.h>#include <sys/msg.h>#include <sys/ipc.h>#define MSGKEY 75 /* 通信雙方約定的隊列關鍵字*/struct msgform /* 消息結構 */ long mtype; /* 消息類型 */char mtext1030; /* 消息正文 */msg;int msgqid; /* 消息隊列描述符 */void Client() int i; /* 局部變量i
9、,消息類型(表示第幾條消息)*/ msgqid=msgget(MSGKEY,0777); /* 創建消息隊列, 訪問權限為777 */ for(i=10;i>=1;i-) msg.mtype=i; /* 指定消息類型 */ printf("(client %d) sent.n",i); /* 打印消息類型 */ msgsnd(msgqid,&msg,1024,0); /* 發送消息msg到msgqid消息隊列,可以先把消息正文放到msg.mtext中*/ sleep(1);/*使進程掛起1秒。等待接收進程接收。比較加上這一句和不加這一句的結果 */ exit(
10、0);void Server() /* 獲得關鍵字對應的消息隊列描述符 */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); /* 創建子進程;如果創建失敗,執行空語句 */ if(!i) Server(); /* 如果i=0,在子進程中,運行Server */ else /* 否則,在父進程中*/ while(i=fork()=-1); /* 繼續創建子進程 */ if(!i) Client(); /* 如果i=0,在子進程中,運行Client */ wait(0); /* 等待子進程結束 */ wait(0); /* 等待子進程結束 */注:IPC進程間通信(Inter-Process Communication)就是指多個進程之間相互通信,交換信息的方法。
12、(3)上機操作創建 msg.c 源文件,編譯 gcc o msg msg.c,運行 ./msg觀察屏幕,記錄結果。 簡答:程序中有,sleep(1);/*使進程掛起1秒。等待接收進程接收。比較加上這一句和不加這一句的結果 */,試分析為什么會有這樣的運行結果差異。(4)課堂練習(1)修改上述程序,讓Client向Server發送一個字符串“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 /* 通信雙方約定的隊列關鍵字*/struct msgform /* 消息結構 */ 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); /* 創建消
14、息隊列, 訪問權限為777 */ /* 指定消息類型 */ printf("(client 1) sent.n"); /* 打印消息類型 */ msgsnd(msgqid,&msg,strlen(msg.mtext),0); /* 發送消息msg到msgqid消息隊列,可以先把消息正文放到msg.mtext中,strlen(msg.mtext)*/ exit(0);void Server() /* 獲得關鍵字對應的消息隊列描述符 */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); /* 創建子進程 */ if(!i) Server(); /* 子進程Server */ else while(i=fork()=-1); /* 創建子進程
16、 */ if(!i) Client(); /* 子進程Client */ wait(0); /* 等待子進程結束 */ wait(0); /* 等待子進程結束 */(5)思考:1、進程的消息傳遞機制和全局變量是一個概念嗎?消息是通過全局變量進行傳遞的嗎?/msg2.c#include <stdio.h>#include <sys/types.h>#include <sys/msg.h>#include <sys/ipc.h>#define MSGKEY 75 /* 通信雙方約定的隊列關鍵字*/struct msgform /* 消息結構 */ 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); /* 創建子進程 */ if(!i) Server(); /* 子進程Server */ else while(i=fork()=-1); /* 創建子進程 */ if(!i) Client(); /* 子進程Client */ wait(0); /* 等待子進程結束 */ wait(0); /* 等待子進程結束 */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 /* 通信雙方約定的隊列關鍵字*/struct msgform /* 消息結構 */ 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); /* 創建子進程 */ if(!i) Server(); /* 子進程Server */ else while(i=fork()=-1); /* 創建子進程 */ if(!i) Client(); /* 子進程Client */ wait(0); /* 等待子進程結束 */ wait(0); /* 等待子進程結束 */2. 在主函數里面改變全局變量是可以傳遞消息的,因為這是父進程,server是子進程,子進程繼承父進程的全部代碼和資源。 3.換個位置又不行了哦,想想是為什么!有沒有暈了呢!/
22、msg2.c#include <stdio.h>#include <sys/types.h>#include <sys/msg.h>#include <sys/ipc.h>#define MSGKEY 75 /* 通信雙方約定的隊列關鍵字*/struct msgform /* 消息結構 */ 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); /* 創建子進程 */ if(!i) Server(); /* 子進程Server */ else while(i=fork()=-1); /* 創建子進程 */ if(!i) printf("sta
24、r copyn"); strcpy(msg.mtext,"The message here is just a joke."); printf("end copyn"); Client(); /* 子進程Client */ wait(0); /* 等待子進程結束 */ wait(0); /* 等待子進程結束 */簡單的說,不同的進程使用的內存空間是不共用的,全局變量只是在同一個進程所占用的內存空間中是全局變量,而其他的進程空間是根本看不到這個變量的。父子進程不共享數據空間、堆、和棧。所以不存在共享全局變量。進程間只能IPC。2、修改上述程序,讓
25、Client向Server發送兩個字符串“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 /* 通信雙方約定的隊列關鍵字*/struct msgform /* 消息結構 */ long mtype; /* 消息類型 */char mtext1024; /* 消息正文 */msg
26、;int msgqid; /* 消息隊列描述符 */void Client() msgqid=msgget(MSGKEY,0777); /* 創建消息隊列, 訪問權限為777 */ /* 指定消息類型 */消息1發送msg.mtype=1; strcpy(msg.mtext,"Thank you."); printf("(client 1) sent.n"); /* 打印消息類型 */ msgsnd(msgqid,&msg,strlen(msg.mtext),0); /* 發送消息msg到msgqid消息隊列,可以先把消息正文放到msg.mtext中,strlen(msg.mtext)*/消息2發送msg.mtype=2; strcpy(msg.mtext,&quo
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經權益所有人同意不得將文件中的內容挪作商業或盈利用途。
- 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 微生物檢驗對提升醫療質量的影響試題及答案
- 部門2025年終工作總結(6篇)
- 總店長述職報告
- 2025年行業競爭意識試題及答案
- 微生物技術與臨床醫學結合的未來展望試題及答案
- 醫院保衛科個人年終總結(12篇)
- 理解項目質量評估方法的相關考題試題及答案
- 項目管理認證考試面臨挑戰試題及答案
- 2025年銀行從業資格證考試實戰指導試題及答案
- 2025至2031年中國聚四氟乙烯懸浮中粒料行業投資前景及策略咨詢研究報告
- 水下潛水艇課件
- 糖尿病酮癥酸中毒護理
- 36 階段統計項目風險管理表甘特圖
- 陜西氣象部門招聘筆試真題2024
- 2025-2030中國電信增值行業運行狀況與發展前景預測研究報告
- 學校中層干部選拔任用實施方案
- 2025年吉林鐵道職業技術學院單招職業傾向性考試題庫含答案
- 品牌總監的面試題及答案
- 電氣工程及其自動化畢業論文-基于PLC的高空作業車電控系統設計
- 貴州高品質住宅設計導則
- 裝修公司設計經理述職報告
評論
0/150
提交評論