




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
操作系統(tǒng)實驗報告實驗三、進程通信(一)——管道及共享內(nèi)存一、 實驗?zāi)康氖煜ず驼莆誏INUX系統(tǒng)的管道通信和共享內(nèi)存通信。二、 實驗內(nèi)容(一)、管道通信1、實驗原理:管道是半雙工的,數(shù)據(jù)只能向一個方向流動;需要雙方通信時,需要建立起兩個管道;單獨構(gòu)成一種獨立的文件系統(tǒng):管道對于管道兩端的進程而言,就是一個文件,但它不是普通的文件,它不屬于某種文件系統(tǒng),而是自立門戶,單獨構(gòu)成一種文件系統(tǒng)。數(shù)據(jù)的讀出和寫入:一個進程向管道中寫的內(nèi)容被管道另一端的進程讀出。利用系統(tǒng)調(diào)用pipe()可創(chuàng)建一個簡單的管道。intfd[2];pipe(fd);調(diào)用成功,fd[0]存放供讀進程使用的文件描述符(管道出口),fd[1]存放供寫程使用的文件描述符(管道入口)。一個進程在由pipe()創(chuàng)建管道后,一般再fork()一個子進程,然后通過管道實現(xiàn)父子進程間的通信,子進程將從父進程那里繼承所有打開的文件描述符。則父子兩個進程都能訪問組成管道的兩個文件描述符,這樣子進程可以向父進程發(fā)送消息(或者相反)。發(fā)送進程利用文件系統(tǒng)的系統(tǒng)調(diào)用write(fd[1],buf,size),把buf中size個字符送入fd[1],接收進程利用read(fd[0],buf,size),把從fd[0]讀出的size個字符置入buf中。這樣管道按FIFO(先進先出)方式傳送信息。2、實驗內(nèi)容:#include<stdio.h>main(){intx,fd[2];charbuf[30],s[30];pipe(fd);while((x=fork())==-1);if(x==0){close(fd[0]);printf("ChildProcess!\n");strcpy(buf,"Thisisanexample\n");write(fd[1],buf,30);exit(0);}else{close(fd[1]);printf("ParentProcess!\n");read(fd[0],s,30);printf("%s\n",s);printf("xvalueinParentProcess:%d!\n",x);}}1)閱讀上述父子進程利用管道進行通信的例子,寫出程序的運行結(jié)果并分析。程序運行x=fork()后,創(chuàng)建里一個子進程,在子進程里 x的返回值為0,在父進程里x的返回值為7684,則子進程會執(zhí)行 if語句里的代碼段,先關(guān)閉了管道的讀入端,再在屏幕上輸出“ChildProcess!”,然后將“Thisisanexample\n”存入buf數(shù)組中,通過調(diào)用 write()函數(shù)將buf數(shù)組的內(nèi)容從管道的寫入端寫入,而父進程會執(zhí)行 else語句里的代碼段,先關(guān)閉了管道的寫入端,再在屏幕上輸出“ParentProcess!”,然后通過調(diào)用read()函數(shù)將buf數(shù)組的內(nèi)容從管道的讀入端讀入冰存儲在s數(shù)組里,接著通過printf()函數(shù)將s數(shù)組里的內(nèi)容輸出到屏幕上,最后在屏幕上輸出父進程中x的值。2)編寫程序:父進程利用管道將一字符串交給子進程處理。子進程讀字符串,將里面的字符反向后再交給父進程,父進程最后讀取并打印反向的字符串。#include<stdio.h>main(){inti,x,fd[2];charbuf[20],s[20],cpy[20],m[20];strcpy(buf,"Thisisanexample\n");pipe(fd);write(fd[1],buf,20);while((x=fork())==-1);if(x==0){printf("ChildProcess!\n");read(fd[0],s,20);for(i=0;i<20;i++){cpy[i]=s[19-i];}write(fd[1],cpy,20);exit(0);}else{close(fd[1]);printf("ParentProcess!\n");read(fd[0],m,20);printf("%s\n",m);}}(二)、共享內(nèi)存通信1、實驗原理:UNIXSystemVIPC軟件包分三個組成部分:共享存儲器(sharedmemory)方式可使得不同進程通過共享彼此的虛擬空間而達到互相對共享區(qū)操作和數(shù)據(jù)通信的目的。消息(message)用于進程之間傳遞分類的格式化數(shù)據(jù)。信號量(semaphore)機制用于通信進程之間往前推進時的同步控制。信號量總是和共享存儲器方式一起使用。操縱共享內(nèi)存共有4個系統(tǒng)調(diào)用:(1)shmget():建立一個新的共享區(qū)或返回一個已存在的共享存儲區(qū)描述字;intshmget(key_tkey,intsize,intshmflag);成功,返回共享內(nèi)存段的標識符;失敗,返回-1,設(shè)置errno。①第一個參數(shù)key(鍵值),預(yù)定義的數(shù)據(jù)類型key_t,其類型是長整型。用來創(chuàng)建IPC標識符,shmget()返回的標識符與key值一一對應(yīng),不同的key值返回不同的標識符。②第二個參數(shù)size,決定了共享內(nèi)存段的大?。ㄈ粼L問已存在的內(nèi)存段,該參數(shù)可設(shè)為0)。有最大字節(jié)數(shù)的限制,0x2000000=32M;③第三個參數(shù)shmflag,用于設(shè)置訪問權(quán)限及標識創(chuàng)建條件。#defineIPC_PRIVATE((key_t)0)#defineIPC_CREAT00001000(八進制)#defineIPC_EXCL00002000(八進制)key值為IPC_PRIVATE時,調(diào)用shmget()將生成一個新的共享內(nèi)存段。Shmflag為0666|IPC_CREAT時,如果key值是新的,返回新創(chuàng)建的內(nèi)存段標識符。若key值是舊的,返回已存在內(nèi)核中的具有相同關(guān)鍵字值的內(nèi)存段標識符。(2)shmat():連接內(nèi)存段,映射到自己的地址空間中;intshmat(intshmid,void*shmaddr,intshmflag);成功:返回該共享內(nèi)存段連接到調(diào)用進程地址空間上的地址(指針)錯誤:返回-1。第一個參數(shù)shmid,是一個有效的共享內(nèi)存標識符;第二個參數(shù)shmaddr,非0,該值作為掛接的地址,設(shè)為0,則由系統(tǒng)來選擇掛接地址;第三個參數(shù)shmflag,可指定掛接后的訪問權(quán)限,(默認情況0)。(3)shmdt():當某個進程不需要一個共享內(nèi)存段時,調(diào)用該系統(tǒng)調(diào)用,斷開與該內(nèi)存段的連接。intshmdt(void*shmaddr);成功:返回0;錯誤:返回-1。參數(shù)shmaddr指向一個已掛接的內(nèi)存段。(4)shmctl():用戶對一個存在的共享內(nèi)存段進行一系列的操作;intshmctl(intshmid,intcmd,structshmid_ds*buf);成功:返回0;錯誤:返回-1,設(shè)置errno。第一個參數(shù)shmid,前面shmget()調(diào)用返回的有效的共享內(nèi)存標識符;第二個參數(shù)cmd,指明shmctl將要執(zhí)行的操作;第三個參數(shù)buf,指向一個shmid_ds類的結(jié)構(gòu)。Cmd可執(zhí)行的操作:(這些也是在/usr/include/linux/ipc.h中定義的)IPC_STAT:返回由shmid值指定的存貯段shmid_ds結(jié)構(gòu)的當前值。IPC_SET:修改shmid_ds結(jié)構(gòu)中反問權(quán)限子結(jié)構(gòu)的若干成員IPC_RMID:刪除shmid指向的內(nèi)存段(并非真正刪除,只有當前連接到該內(nèi)存段的最后一個進程正確地斷開了與它的連接,實際的刪除操作才會發(fā)生) 。附:1、ipcs命令的作用:用于查看系統(tǒng)中共享存儲區(qū),消息隊列和信號量的情況。2、ipcrm命令的作用:用于刪除系統(tǒng)中存在的共享存儲區(qū), 消息隊列等。如:ipcrm -Mkey表示根據(jù)關(guān)鍵字刪除共享存儲區(qū)ipcrm-mid表示根據(jù)標識符刪除共享存儲區(qū)ipcrm-Qkey表示根據(jù)關(guān)鍵字刪除消息隊列ipcrm-qid表示根據(jù)標識符刪除消息隊列2、實驗內(nèi)容:(1)閱讀例2的程序,運行一次該程序,然后用ipcs命令查看系統(tǒng)中共享存儲區(qū)的情況,再次執(zhí)行該程序,再用ipcs命令查看系統(tǒng)中共享內(nèi)存的情況,對兩次的結(jié)果進行比較,并分析原因。最后用ipcrm命令刪除自己建立的共享存儲區(qū)。#include<sys/types.h>#include<sys/ipc.h>#include<sys/shm.h>main(){key_tkey=69;intshmid_1,shmid_2;if((shmid_1=shmget(key,1000,0644|IPC_CREAT))==-1){perror("shmgetshmid_1");exit(1);}printf("Firstsharedmemoryidentifieris%d\n",shmid_1);if((shmid_2=shmget(IPC_PRIVATE,20,0644))==-1){perror("shmgetshmid_2");exit(2);}printf("Secondsharedmemoryidentifieris%d\n",shmid_2);exit(0);}key值為IPC_PRIVATE時,調(diào)用shmget()將生成一個新的共享內(nèi)存段。(2)每個同學(xué)登陸兩個窗口,先在一個窗口中運行例 3程序1(或者只登陸一個窗口,先在該窗口中以后臺方式運行程序1),然后在另一個窗口中運行例3程序2,觀察程序的運行結(jié)果并分析。運行結(jié)束后可以用ctrl+c結(jié)束程序1的運行。例3:(程序1)#include<sys/types.h>#include<sys/ipc.h>#defineSHMKEY69#defineK 1024intshmid;main(){inti,*pint;char*addr;externchar*shmat();externcleanup();for(i=0;i<20;i++)signal(i,cleanup);shmid=shmget(SHMKEY,16*K,0777|IPC_CREAT);/*建立16K共享區(qū)SHMKEY*/addr=shmat(shmid,0,0);/*掛接,并得到共享區(qū)首地址 */printf("addr0x%x\n",addr);pint=(int*)addr;for(i=0;i<256;i++)*pint++=i;pause();/*等待接收進程讀 */}cleanup(){shmctl(shmid,IPC_RMID,0);exit();}例3:(程序2)#include<sys/types.h>#include<sys/ipc.h>#defineSHMKEY69#defineK 1024intshmid;main(){inti,*pint;char*addr;externchar*shmat();shmid=shmget(SHMKEY,8*K,0777);/*取共享區(qū)SHMKEY的id*/addr=shmat(shmid,0,0);/*連接共享區(qū)*/pint=(int*)addr;for(i=0;i<256;i++)printf("%d",*pint++);/* 打印共享區(qū)中的內(nèi)容*/}在后臺運行的例3的程序1:首先系統(tǒng)通過調(diào)用shmctl()對shmid指向的內(nèi)存段進行刪除操作,接著系統(tǒng)調(diào)用shmget()創(chuàng)建一個16K的共享內(nèi)存段,成功返回共享內(nèi)存段的標識符給shmid,系統(tǒng)再次調(diào)用shmat()連接內(nèi)存段,返回共享內(nèi)存段連接到調(diào)用進程地址空間上的地址addr,最后向該共享內(nèi)存段中寫入數(shù)據(jù);終端運行的例3的程序2:首先系統(tǒng)調(diào)用shmget()創(chuàng)建一個8K的共享內(nèi)存段,由key與程序1相同,所以返回給shmid的值與程序1所創(chuàng)建的共享內(nèi)存段的標識符相同,再通過調(diào)用shmat()掛接內(nèi)存段,由shmid與程序1相同,所以掛接到程序1所創(chuàng)建的共享內(nèi)存段,最后讀取該共享內(nèi)存段的數(shù)據(jù)并輸出到屏幕上。(3)編寫程序:使用系統(tǒng)調(diào)用shmget(),shmat(),shmdt(),shmctl(),編制程序。要求在父進程中生成一個30字節(jié)長的私有共享內(nèi)存段。接下來,設(shè)置一個指向共享內(nèi)存段的字符指針,將一串大寫字母寫入到該指針指向的存貯區(qū)。調(diào)用fork()生成子進程,讓子進程顯示共享內(nèi)存段中的內(nèi)容。接著,將大寫字母改成小寫,子進程修改共享內(nèi)存中的內(nèi)容。之后,子進程將脫接共享內(nèi)存段并退出。父進程在睡眠5秒后,在此顯示共享內(nèi)存段中的內(nèi)容(此時已經(jīng)是小寫字母) 。#include<sys/types.h>#include<sys/ipc.h>#include<sys/shm.h>#defineSHMKEY69#defineK 1024intshmid_1,shmid_2;main(){intx,y,i,*pint;char*addr_1,*addr_2;charwords[26]={'A','B','C','D','E','F','G','H','I','J','K','L','M
溫馨提示
- 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)容負責。
- 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 醫(yī)護工作服采購合同
- 維修保養(yǎng)合同范本:機械設(shè)施
- 高級顧問聘用合同
- 合伙協(xié)議合同簡化版范本
- 酒店投資合作合同范本
- 化學(xué)品運輸服務(wù)承包合同
- 私人裝修合同協(xié)議書范本
- 企業(yè)設(shè)備抵押融資合同樣本
- 寵物臨時寄養(yǎng)服務(wù)合同范本
- 合同簽約盛宴:五十二條經(jīng)典致辭美句鑒賞
- 單晶爐車間安全培訓(xùn)
- 高中地理必修第一冊期末試卷及答案-中圖版-2024-2025學(xué)年
- 護理核心制度測試題+參考答案
- 機械制造技術(shù)基礎(chǔ)(課程課件完整版)
- 《2023版CSCO卵巢癌診療指南》解讀課件
- 《預(yù)防未成年人犯罪》課件(圖文)
- 【醫(yī)院藥品管理系統(tǒng)探析與設(shè)計(論文)10000字】
- 螺旋體病梅毒課件
- 2024年咸寧市引進人才44名歷年高頻難、易錯點500題模擬試題附帶答案詳解
- (小學(xué)組)全國版圖知識競賽考試題含答案
- 人教版一年級道德與法治下冊全冊教案
評論
0/150
提交評論