版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
第第頁操作系統(tǒng)管道通信河南城建學(xué)院
《操作系統(tǒng)》課程設(shè)計說明書
設(shè)計題目:管道通信
專業(yè):計算機(jī)科學(xué)與技術(shù)
指導(dǎo)老師:邵國金郭猛薛冰
班級:0814102
學(xué)號:081410217
姓名:金賀
同組人:李乾坤邵光光
計算機(jī)科學(xué)與工程系
2022年1月10日
授課:***
前言
課程設(shè)計是檢測同學(xué)課程效果的重要手段,是訓(xùn)練同學(xué)通過所學(xué)的知識解決實際問題的重要方式,同時也是實踐性教學(xué)中的一個重要環(huán)節(jié),它以某以課程為基礎(chǔ),可以涉及和課程相關(guān)的各個方面,是一門獨立于課程之外的非常課程。課程設(shè)計是讓同學(xué)對所學(xué)的課程更全面的學(xué)習(xí)和應(yīng)用,理解和掌控課程的相關(guān)知識。《操作系統(tǒng)》是一門重要的專業(yè)課,是計算機(jī)理論和應(yīng)用的核心基礎(chǔ)課程。
操作系統(tǒng)課程設(shè)計,是一次對多學(xué)知識的綜合演練,要求同學(xué)在操作系統(tǒng)的設(shè)計理念、整體機(jī)構(gòu)、模塊劃分、數(shù)據(jù)結(jié)構(gòu)的選擇和應(yīng)用、算法的設(shè)計及其實現(xiàn)等方面,加深對課程基本內(nèi)容的理解,同時,在課程設(shè)計方法以及上機(jī)操作等基本技能和科學(xué)作風(fēng)方面收到比較系統(tǒng)和嚴(yán)格的訓(xùn)練。
在這次的課程設(shè)計中我們選擇的題目是進(jìn)程間通信消息機(jī)制的設(shè)計,實現(xiàn)消息的創(chuàng)建、發(fā)送和接收及在server端創(chuàng)建一個服務(wù)函數(shù),從而形成C/S通訊模式。消息機(jī)制是消息通過消息隊列的方式進(jìn)行進(jìn)程間消息的傳遞,通過此次課程設(shè)計,全面理解消息機(jī)制進(jìn)程間通信方法。實現(xiàn)把死板的課本知識變得生動有趣,激發(fā)了同學(xué)的積極性。把學(xué)過的計算機(jī)操作系統(tǒng)的知識強(qiáng)化,能夠把課堂上的知識通過自己設(shè)計的程序表示出來,加深了歲理論知識的理解目的。
授課:***
目次
一、(4)
二、(4)
三、設(shè)計題目及要求(4)
(1)設(shè)計管道通信(4)
(2)設(shè)計命名管道(4)
四、總體設(shè)計(4)
五、具體設(shè)計(6)
1、實現(xiàn)管道通信(6)
2、命名管道設(shè)計(8)
六、調(diào)試與測試方法(12)
七、執(zhí)行結(jié)果及分析(13)
八、源程序清單(14)
九、心得體會(19)
十、
#includestdio.h
main()
{
inti,r,p1,p2,fd[2];
charbuf[50],s[50];
pipe(fd);//創(chuàng)建匿名管道,fd[0]為讀端,fd[1]為寫端//
while((p1=fork())==-1);//創(chuàng)建子進(jìn)程P1,直至勝利為止〔p1!=-1〕//
if(p1==0)//子進(jìn)程P1執(zhí)行規(guī)律//
{
lockf(fd[1],1,0);//鎖定管道寫端,保證寫入數(shù)據(jù)的完整性//
sprintf(buf,childprocessP1issendingmessages!\n);//在buf中填入預(yù)備寫入管道的信息數(shù)據(jù)printf(childprocessP1!\n);//打印“子進(jìn)程P1正在運行”//
write(fd[1],buf,50);//向管道寫端fd[1]寫入buf中的數(shù)據(jù),寫完后該數(shù)據(jù)即可以從讀端fd[0]讀出//
sleep(5);//睡眠5秒//
lockf(fd[1],0,0);//解鎖管道寫端//
e*it(0);//子進(jìn)程P1退出//
}
else//主進(jìn)程的執(zhí)行規(guī)律//
{
while((p2=fork())==-1);//創(chuàng)建第二個子進(jìn)程P2//
if(p2==0)//子進(jìn)程P2的執(zhí)行規(guī)律//
{
lockf(fd[1],1,0);//鎖定管道寫端,保證數(shù)據(jù)寫入完整//
sprintf(buf,childprocessP2issendingmessages!\n);//在buf中填入預(yù)備寫入管道的信息數(shù)據(jù)
授課:***
printf(childprocessP2!\n);//打印“子進(jìn)程P2正在運行”//
write(fd[1],buf,50);//向管道寫端fd[1]寫入buf中的數(shù)據(jù),寫完后該數(shù)據(jù)即可從讀端fd[0]讀出//
sleep(5);//睡眠5秒//
lockf(fd[1],0,0);//解鎖管道寫端//
e*it(0);//子進(jìn)程P2退出//
}
//以下為主進(jìn)程執(zhí)行規(guī)律//
wait(0);//等待某個子進(jìn)程退出//
if(r=read(fd[0],s,50)==-1)//從管道讀端fd[0]讀取P1或者P2寫入的數(shù)據(jù)〔視哪個子進(jìn)程搶先執(zhí)行到lockf函數(shù)〕//
{
printf(:cantreadpipe\n);//讀取失敗,打印錯誤信息//
}
else
{
printf(:%s\n,s);//打印出讀到的信息數(shù)據(jù)//
}
wait(0);//等待第二個子進(jìn)程退出//
if(r=read(fd[0],s,50)==-1)//從管道讀端fd[0]讀取出P1或者P2寫入的數(shù)據(jù)〔視哪個子進(jìn)程后執(zhí)行到lockf函數(shù)〕//
{
printf(:cantreadpipe\n);//讀取失敗,打印錯誤信息//
}
else
{
printf(:%s\n,s);//打印讀取到的信息數(shù)據(jù)//
}
e*it(0);//主進(jìn)程退出//
}
}
2、命名管道設(shè)計。
命名管道的通信例子中包括client端和server端。它們源代碼文件名稱分別為fifo_clt.c和fifo_svr.c,還有一個公共常量的有關(guān)文件被打包在文件fifo_hd.h
運行時,client只運行一次就將退出,而server端作為服務(wù)器仍將繼續(xù)運行,你再次啟動client來懇求服務(wù)。
FIFO的用法
1、創(chuàng)建
用mkfifo或mknod創(chuàng)建一個命名管道。以mkfifo為例:
#includesys/types.h
#includesys/stat.h
intmkfifo(constchar*fifo_name,mode_tmode);//勝利返回0,否那么為-1
授課:***
2、運用
管道一經(jīng)創(chuàng)建,就可向一般文件一樣運用。可通過系統(tǒng)調(diào)用open,close,read,write,unlink等進(jìn)行操作。
管道打開過程中,變量O_NONBLOCK將影響打開后對文件的操作。默認(rèn)狀況下該變量不設(shè)置,也就是以堵塞方式打開。這樣可以保證原子性操作。〔因此可以不考慮該參數(shù)。〕在操作過程中,假如對一個管道進(jìn)行寫操作write,假設(shè)對方?jīng)]有以讀方式打開將產(chǎn)生SIGPIPE。你可以捕獲此信號進(jìn)行處理。默認(rèn)狀況下是涌現(xiàn)寫錯誤。當(dāng)最末一個寫入者關(guān)閉了管道,將產(chǎn)生一個文件結(jié)束標(biāo)識EOF。
3、client、server
可以以client/server方式運用FIFO。假如一個服務(wù)器有多個客戶時,每個客戶可通過一個well_knownFIFO服務(wù)器連接。連接后可以通過well_knownFIFO向服務(wù)器發(fā)送懇求,所發(fā)信息的長度需要≤PIPE_BUF(4096)。
假如客戶服務(wù)器模式是并發(fā)型的話,那么客戶機(jī)不能再通過well_knownFIFO回讀信息。此時可采納在已連接的客戶與服務(wù)器之間建立一個私有通訊管道的方法來進(jìn)行通信。該私有管道被服務(wù)器創(chuàng)建后可以以I/O方式打開,用于客戶機(jī)和服務(wù)器之間進(jìn)行通訊,以完成指定性工作。
頭文件
#definemy_fifomy_fifo/*定義頭文件名*/
#definefile_nameserver./*定義頭文件名*/
客戶端程序
#includestdio.h
#includesys/types.h
#includesys/stat.h
#includefifo_hd.h
main(intargc,char**argv)
{
intfd1,fd2,pid,pid1;/*定義管道*/
charmy_buf[100];
charmy_fil[100];
charmy1buf[100];
if((fd1=open(my_fifo,1))==-1)
{
授課:***
fprintf(stderr,Openwell_knownFIFOforreadindError!\n);
e*it(-1);/*失敗*/
}
fprintf(stderr,Open%sOK!\n,my_fifo);
pid=getpid();
sprintf(my_buf,%5.5d%6.6d%7.7d,pid,pid*10,pid*20);
if(write(fd1,my_buf,20)!=0){
strcpy(my_fil,file_name);/*拷貝*/
strncat(my_fil,my_buf,5);
fprintf(stderr,Send_fil:%s\n,my_fil);
sleep(2);
if((fd2=open(my_fil,2))==-1){
fprintf(stderr,open%sError!\n,my_fil);
close(fd1);
e*it(-2);
}
fprintf(stderr,open%sOK!\n,my_fil);
if(read(fd2,my1buf,5)!=0){
my1buf[5]=\0;
fprintf(stderr,Readfrommy_buf:%s!\n\tmy1buf:%s,my_buf,my1buf);
if(strncmp(my_buf,my1buf,5)!=0){
fprintf(stderr,Differentoccurs!\n);
}
strcpy(my_buf,0000000000);
write(fd2,my_buf,5);
//sleep(5);
close(fd2);
close(fd1);
}
}
}
服務(wù)器程序
#includestdio.h
#includesignal.h
#includesys/types.h
#includesys/stat.h
#includefifo_hd.h
voidterminate();
intwell_known_id,tmp_id;
chartmp_fil[100];
main(intargc,char**argv)
{
授課:***
intfd1,fd2;
pid_tpid;
charmy_buf[100],my_fil[100],my_tmp[100];
sprintf(my_buf,rm-f%s/dev/null,my_fifo);
system(my_buf);//doshellcmdrm-fmy_fifo/dev/null
well_known_id=tmp_id=-1;
signal(SIGINT,terminate);
if(mkfifo(my_fifo,S_IRW*U|S_IRW*G|S_IRW*O)==-1){
fprintf(stderr,CreateWell_knownFIOFError!\n);
e*it(-1);/*創(chuàng)建失敗*/
}
fprintf(stderr,mkfifoOK!\n);
fprintf(stderr,ANewSeession!Imwaitingconnection...\n);loop1:/*輸出字符串*/
if((fd1=open(my_fifo,0))==-1){
fprintf(stderr,Openwell_knownFIFOforreadindError!\n);
unlink(my_fifo);/*斷鏈接*/
e*it(-2);
}
well_known_id=fd1;
tmp_id=-1;
fprintf(stderr,openmy_fifoOK!\n);
if(read(fd1,my_buf,20)!=0){
fprintf(stderr,My_buff=%s\n,my_buf);
strcpy(my_fil,file_name);
strncat(my_fil,my_buf,5);
strcpy(tmp_fil,my_fil);
}
if((pid=fork())!=0){
close(fd1);
wait();
gotoloop1;
}
fprintf(stderr,Tmp_FIFOis:%s|\n,my_fil);
if(mkfifo(my_fil,S_IRW*U|S_IRW*G|S_IRW*O)==-1){
fprintf(stderr,Createmy_fil:%sFIFOError!\n,my_fil);
e*it(-1);/*錯誤*/
}
//system(lsserver*);
if((fd2=open(my_fil,2))==-1){
fprintf(stderr,Open%sError!:%d\n,my_fil,fd2);
close(fd1);unlink(my_fifo);
e*it(-3);
授課:***
}
tmp_id=fd2;
if(write(fd2,my_buf,5)!=5){
fprintf(stderr,Write%sError!\n,my_fil);
close(fd2);close(fd1);
unlink(my_fil);unlink(my_fifo);
e*it(-4);/*退出*/
}
sleep(1);
if(read(fd2,my_tmp,5)!=5){
fprintf(stderr,read%sError!\n,my_fil);
close(fd2);close(fd1);
unlink(my_fil);unlink(my_fifo);
e*it(-5);/*退出*/
}
else{
if(strncmp(my_tmp,00000,5)!=0){
close(fd2);close(fd1);
fprintf(stderr,Filedtofinishtalkingwith%s!\n,my_fil);
unlink(my_fil);
e*it(-1);/*失敗*/
//gotoloop1;
}
else{
close(fd2);close(fd1);
fprintf(stderr,OKtotalkingwith%s!\n,my_fil);
unlink(my_fil);
//unlink(my_fifo);
e*it(0);/*勝利實現(xiàn)管道通信*/
}
}
}
voidterminate()
{
if(well_known_id!=-1){
close(well_known_id);unlink(my_fifo);
}
if(tmp_id!=-1){
close(tmp_id);unlink(tmp_fil);
}
fprintf(stderr,TheServerProgramstopedbySignal:SIGINT!\n);
e*it(0);
}
七、調(diào)試與測試
授課:***
任務(wù)一編譯方法:
編譯:
ccliulong.c
執(zhí)行:
./a.out
結(jié)果:
任務(wù)二編譯方法是:
編譯:
cc–ofifo_svrfifo_srv.c
cc–ofifo_cltfifo_client.c
執(zhí)行:
先啟動server端程序,方法為:
./fifo_svr
服務(wù)端:
再換一個終端運行client端,方法是:
授課:***
./fifo_clt
客戶端:
運行時,client只運行一次就將退出,而server端作為服務(wù)器仍將繼續(xù)運行,你再次啟動client來懇求服務(wù)。
任務(wù)一運行結(jié)果正常:管道實現(xiàn)通信
任務(wù)二運行結(jié)果涌現(xiàn)錯誤如下:
服務(wù)器運行起初正常,然后當(dāng)與客戶端建立通信時由于客戶端程序出錯,導(dǎo)致整個通信涌現(xiàn)錯誤。
授課:***
授課:
***
由客戶端引起的服務(wù)器程序運行涌現(xiàn)錯誤
當(dāng)服務(wù)器輸送文件時,打開服務(wù)器涌現(xiàn)錯誤繼續(xù)結(jié)果一樣:
客戶端程序運行涌現(xiàn)錯誤
服務(wù)器等待通信連接:
服務(wù)器程序正常運行
八、設(shè)計中遇到的問題及解決方法
在編寫無名管道前了解到pipe〔〕創(chuàng)建的管道只能實現(xiàn)父子進(jìn)程或者兄弟進(jìn)程之間的通信,但是還是遇到了以下幾個問題:1、怎樣實現(xiàn)不同子進(jìn)程互斥的訪問管道?2、是各個子進(jìn)程都寫完之后父進(jìn)程一起讀,還是在每個子進(jìn)程一寫完父進(jìn)程就立刻讀,那么怎樣去通知父進(jìn)程去讀呢?經(jīng)過查閱相關(guān)資料得知,為解決第一個問題而引入了lockf〔〕函數(shù)用于實現(xiàn)上鎖與解鎖,此函數(shù)放在讀寫之前執(zhí)行。為解決第二問題而引入sleep〔〕和wait〔〕函數(shù)用以實現(xiàn)睡眠與等待。
在編寫出名管道前經(jīng)查閱相關(guān)資料得知用mknod〔〕或者mkfifo〔〕函數(shù)調(diào)用創(chuàng)建出名管道從而實現(xiàn)在任意兩個文件間的通信,該管道可以像一般文件一樣read、write、open。由于這是個新接觸的知識,以往沒有練習(xí)過,所以涌現(xiàn)的問題較多:首先,怎樣才能實現(xiàn)客戶/服務(wù)器模式,使其可在兩個終端上交互運行?其次,怎樣掌握讀寫以及輸入輸出?經(jīng)過查閱相關(guān)資料仿照、拷貝、小組爭論即可得出基本模塊。最末運用signal(SIGINT,terminate)函數(shù)發(fā)送中斷信號退出程序。經(jīng)調(diào)試后最末可在機(jī)器上運行。
九、源程序清單
任務(wù)1
#includeunistd.h
#includesignal.h
#includestdio.h
intpid1,pid2;
main()
{
intfd[2];
charoutpipe[100],inpipe[100];
pipe(fd);
while((pid1=fork())==-1);
if(pid1==0)
{
授課:***
溫馨提示
- 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)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 生物分離原理試題及答案
- 糖尿病足部護(hù)理培訓(xùn)教材
- 2026 年初中英語《陳述句》專項練習(xí)與答案 (100 題)
- 2026年深圳中考語文知識體系構(gòu)建試卷(附答案可下載)
- 2026年深圳中考英語學(xué)困生補(bǔ)差試卷(附答案可下載)
- 《GA 2177-2024移民管理警察冬執(zhí)勤頭盔》專題研究報告
- 2026年大學(xué)大二(教育學(xué))教育統(tǒng)計學(xué)階段測試試題及答案
- 衛(wèi)生類崗位題庫及答案
- 2026年深圳中考生物沖刺名校專項試卷(附答案可下載)
- 面試財務(wù)題庫及答案解析
- 交通運輸安全檢查與處理規(guī)范(標(biāo)準(zhǔn)版)
- UCL介紹教學(xué)課件
- 木工電鋸使用規(guī)范制度
- 骨科跟骨骨折課件
- 2026年美團(tuán)商業(yè)分析師崗位筆試解析與面試問答技巧
- 某高校十五五教育大數(shù)據(jù)治理中心與智慧校園支撐平臺建設(shè)方案
- 2026年山西警官職業(yè)學(xué)院單招綜合素質(zhì)考試備考試題帶答案解析
- 汽修廠文件檔案歸檔制度
- 高??蒲许椖苛㈨椉肮芾硪?guī)范
- 2026年工業(yè)數(shù)字化能碳管理項目可行性研究報告
- 《事故隱患排查治理資金使用專項制度》
評論
0/150
提交評論