




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
1、華南師范大學實驗報告學生姓名 學 號 專 業(yè) 多媒體與網(wǎng)絡技術(shù) 年級、班級 12級多媒體2班 課程名稱 操作系統(tǒng)原理 實驗項目 實驗5 Linux進程及并發(fā)程序設計 實驗類型 驗證 設計 R 綜合 實驗時間 2014 年 4月22日實驗指導老師 實驗評分 實驗5 Linux進程及并發(fā)程序設計 一實驗目的:掌握Linux環(huán)境下的進程并發(fā)程序及管道應用程序的編寫要點。二實驗內(nèi)容:1 編寫一個并發(fā)程序,父進程打印“The Parent is running”,子進程打印“The Child is running”。2 編寫一個并發(fā)程序,父進程打印“The Parent is running”,子進程
2、打印“The Child is running”,并保證子進程輸出在前,父進程輸出在后。3 編寫一個管道應用程序,父進程通過管道提供字符串“put the string into the pipe.”給子進程,子進程通過管道接收這條信息,然后打印輸出。4 調(diào)試并運行3.10的并發(fā)程序設計實例,顯示結(jié)果是什么,并分析之。5 提高題:編寫一個管道應用程序,使父進程接受用戶從鍵盤輸入的數(shù)據(jù)信息并通過管道傳送給子進程,子進程打印輸出通過管道接收到的數(shù)據(jù)信息。3 實驗過程步驟與結(jié)果: (一)編寫一個并發(fā)程序1. 根據(jù)要求編寫程序:#include<stdio.h>main( ) int p;
3、 /存放子進程pid號while( ( p=fork( ) ) =-1); /創(chuàng)建子進程直到成功為止if (p = 0) /返回值=0表示子進程返回 printf("The Child is runningn");else /返回值>0表示父進程返回 printf("The Parent is runningn");2.存放在Linux中的bingfa.c文檔中:3.使用gcc命令對bingfa.c進行編譯:4.多次使用./a.out執(zhí)行該命令,查看結(jié)果:輸出:The Parent is runningThe Child is running或者T
4、he Child is runningThe Parent is running5. 運行結(jié)果分析:通過實驗結(jié)果可看出,這是一個并發(fā)程序,子進程和父進程在不同的情況下先后出現(xiàn)的順序可能不同,具有隨機性。(2) 編寫一個并發(fā)程序(子先父后)1. 根據(jù)要求編寫程序:#include<stdio.h>#include <stdlibh>main( ) int p; /存放子進程pid號while( ( p=fork( ) ) =-1); /創(chuàng)建子進程直到成功為止if (p = 0) /返回值=0表示子進程返回 printf("The Child is running
5、n"); exit(0); / 在子進程結(jié)束時調(diào)用exit(0),使子進程自我終止,并發(fā)終止信號給其父進程;else /返回值>0表示父進程返回 wait(0); /父進程等待子進程終止,再執(zhí)行下方程序 printf("The Parent is runningn"); 2. 存放在Linux中的Childfirst.c文檔中:3. 使用gcc命令對Childfirst.c進行編譯:4.多次使用./a.out執(zhí)行該命令,查看結(jié)果:輸出:The Child is runningThe Parent is running5. 運行結(jié)果分析:從運行結(jié)果可看出此程序
6、實現(xiàn)了父等子的功能,始終是子進程先執(zhí)行。從代碼上看,是用wait(0)和exit(0)實現(xiàn)的,在子進程(p=0)運行后使用exit(0)終止進程,在父進程(p>0)內(nèi)容程序執(zhí)行前加上wait(0),使父進程接收到子進程結(jié)束的信號后才執(zhí)行內(nèi)容程序,從而實現(xiàn)了后執(zhí)行父進程的效果。(3) 編寫一個管道應用程序(父提供給子字符串)1. 根據(jù)要求編寫程序:#include <sys/types.h>#include <unistd.h>#include <stdio.h> /printf函數(shù)的頭文件#include<stdlib.h> /exit函數(shù)
7、的頭文件#define LINESIZE 1024int main(void) int n, fd2; pid_t pid; char lineLINESIZE; if(pipe(fd)<0) /調(diào)用pipe()函數(shù)建立管道; printf("pipe error"); /建立不成功則返回“pipe error",并退出; exit(1); if(pid=fork()<0) /創(chuàng)建進程,創(chuàng)建不成功則返回"fork error"并退出 printf("fork error"); exit(1); else if(p
8、id>0) /父進程的fork()返回 close(fd0); /關(guān)閉管道讀指針; printf("I'm fathern"); /聲明它是父進程 write(fd1, "put the string into the pipe.n",29);/將"put the string into the pipe.n"寫入管道 close(fd1); /關(guān)閉管道寫指針; else /父進程的fork()返回 close(fd1); /關(guān)閉管道寫指針; printf("I'm sonn"); /聲明它是
9、子進程 n=read(fd0,line, LINESIZE);/讀取輸入的信息,存放到字符串line中 printf("string: %sn", line); /輸出”string:“和輸入的信息 close(fd0); /關(guān)閉管道讀指針; exit(0); /退出程序;2. 存放在Linux中的father_to_son.c文檔中:3. 使用gcc命令對father_to_son.c進行編譯:4. 使用./a.out執(zhí)行該命令,查看結(jié)果:輸出:I'm fatherI'm sonstring:put the string into the pipe.5.運
10、行結(jié)果及程序思路分析:通過pipe()函數(shù)建立管道;用close(fd0)關(guān)閉父進程管道讀指針,利用write(fd1, "字符串內(nèi)容",字符串長度);寫入字符串,最后關(guān)閉管道寫指針;用close(fd1)關(guān)閉子進程管道寫指針,利用read(fd0, "字符串內(nèi)容",字符串長度);讀取管道中字符串,最后關(guān)閉管道讀指針;實現(xiàn)父進程向子進程傳遞字符串的功能;(四)調(diào)試運行3.10并發(fā)程序并進行分析1.程序源代碼如下:【father1.c】:【child1.c】:【pipeline.c】:2.執(zhí)行程序:輸入: cc -o child1 child1.c cc
11、-o father1 father1.ccc pipeline.c./a.out 輸出:_Parent is using pipe write.child,child.3. 代碼與運行結(jié)果分析:【father1.c】:#include<stdio.h>#include<stdlib.h>main()static char string="Parent is using pipe write."int len;len=sizeof(string);write(1,string,len); /將"Parent is using pipe wri
12、te."寫入字符串len中printf("parent,parent, parentnnn"); /輸出顯示是parent進程在執(zhí)行exit(0);【child1.c】:#include<stdio.h>main()char output30;read(0,output,30); /讀output中的內(nèi)容printf("_%sn child,child.n",output);/輸出output中的內(nèi)容加上child,child聲明是子進程return(0);【pipeline.c】:#include<stdio.h>#i
13、nclude<stdlib.h>#include<unistd.h>#define STD_INPUT 0 /定義標準輸入設備描述符#define STD_OUTPUT 1 /定義標準輸出設備描述符int fd2;main() static char process1="father1",process2="child1" pipe(fd); /定義管道,返回文件描述符fd0,fd1 pipeline(process1,process2); /調(diào)用自定義函數(shù)pipeline(); exit(1); /程序結(jié)束pipeline(pr
14、ocess1,process2)char *process1,*process2; int i; while(i=fork()=-1); /創(chuàng)建進程,創(chuàng)建失敗則反復創(chuàng)建,直到創(chuàng)建成功 if(i) /父進程的fork()返回 close(fd0); /關(guān)閉管道讀端 close(STD_OUTPUT); /關(guān)閉標準輸出描述符1(原來是寫到顯示器的指針) dup(fd1); /指定標準輸出描述符1為管道寫指針,語句后調(diào)用printf函數(shù),那么內(nèi)容并不會輸出到顯示器,而是寫入了管道中。 close(fd1); /關(guān)閉原始管道寫指針 execl(process1,process1,0); /用程序fat
15、her1覆蓋當前程序 printf("father failed.n");/execl()執(zhí)行失敗時才執(zhí)行這一行 else close(fd1); /關(guān)閉管道寫端 close(STD_INPUT); /關(guān)閉標準輸出描述符0 dup(fd0); /指定標準輸入描述符0為管道讀指針, 語句后調(diào)用scanf函數(shù),那么不會從鍵盤讀取內(nèi)容,而是從管道中讀取。 close(fd0); /關(guān)閉原始管道讀指針 execl(process2,process2,0); /用程序child1覆蓋當前程序 printf("child failed.n");/execl()執(zhí)行失
16、敗時才執(zhí)行這一行 exit(2); /程序結(jié)束4. 運行結(jié)果分析:輸出結(jié)果為:_Parent is using pipe write.child,child. Pipeline.c中調(diào)用了dup(fd1); 指定標準輸出描述符1為管道寫指針,語句后調(diào)用printf函數(shù),那么內(nèi)容并不會輸出到顯示器,而是寫入了管道中。而從結(jié)果可看出,父進程通過管道傳給了子進程“Parent is using pipe write.”(從而才會前面有_,后面有child,child),同時pipeline.c中使用execl(process1,process1,0); 用父進程覆蓋原進程,如果沒有發(fā)揮dup(fd1
17、)的作用(將printf中的內(nèi)容“parent,parent,parent”寫入管道中),也應在界面中打印出來。所以我進行了以下幾個測試:(1) 測試printf是否因write而沒有輸入到管道中(注釋掉write行)輸出了:_parent,parent,parent(3行)child,child出現(xiàn)了“_”和“child,child”,說明dup(fd1)的作用實現(xiàn)了,prinf的內(nèi)容的確輸入到管道中。說明是write導致的。(2) 測試是否由于write和printf的順序?qū)е聼o法寫入(調(diào)換位置)仍然無法輸出,說明不是順序問題;(3) 測試是否發(fā)送接收字符串的問題(是否結(jié)束符0的問題)修改
18、發(fā)送字符串長度:后面出現(xiàn)的pa說明的確是字符串長度的問題;接下來修改接收字符串長度:成功實現(xiàn)prinf內(nèi)容輸入管道并從子進程同時讀取出用write和prinf寫入的內(nèi)容。分析字符串長度為何會導致這種問題:通過上網(wǎng)了解到,用sizeof計算變量的空間大小時,它會把數(shù)組末尾的0符號也計算進去,在你往管道內(nèi)輸入后,讀取時遇見'0'符號就會認為字符串結(jié)束,就不再讀取prinf中的內(nèi)容,而prinf中的內(nèi)容,不管與write命令的順序如何,都只會把內(nèi)容輸入到管道中write的部分。從而,整個程序利用execl();實現(xiàn)father1和child1在同一程序中實現(xiàn),father1通過管道通
19、信傳給了child1字符串;同時利用close(fd)的方式實現(xiàn)進程的互斥。使用dup(fd)實現(xiàn)將外部輸入輸出設備的信息置于管道中,進行讀取。(五)編寫一個管道應用程序(父接收鍵盤輸入傳給子進程)1.根據(jù)要求編寫程序:#include <sys/types.h>#include <unistd.h>#include <stdio.h>#include <signal.h>#include <stdarg.h>#include<stdlib.h>#define LINESIZE 1024int main(void) int
20、 n, fd2; pid_t pid; char lineLINESIZE; fgets(line, sizeof(line), stdin); /獲得鍵盤輸入,存放在字符串line中 if(pipe(fd)<0) /調(diào)用pipe()函數(shù)建立管道; printf("pipe error"); /建立不成功則返回“pipe error",并退出; exit(1); if(pid=fork()<0) /創(chuàng)建進程,創(chuàng)建不成功則返回"fork error"并退出 printf("fork error"); exit(1)
21、; else if(pid>0) close(fd0); /關(guān)閉管道讀指針 printf("I'm fathern"); /聲明它是父進程 write(fd1, line,sizeof(line); /將line中的內(nèi)容(即鍵盤輸入)寫入管道中 close(fd1); /關(guān)閉管道寫指針 else /子進程的fork()返回 close(fd1); /關(guān)閉管道寫指針; printf("I'm sonn"); /聲明它是子進程 n=read(fd0,line, LINESIZE);/讀取輸入的信息,存放到字符串line中 printf("string: %sn", line); /輸出”string:“和輸入的信息 close(fd0); /關(guān)閉管道讀指針 exit(0); /退出程序;2.存放在Linu
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 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. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 農(nóng)村板車出售合同范例
- 保證投資不虧欠合同范例
- 公司崗位合同范例
- 出租 包租 合同范本
- 企業(yè)服務顧問合同范例
- 剛配材料合同范例
- 農(nóng)村樓房安裝電梯合同范例
- 代播協(xié)議合同范例
- 出售二手車交易合同范例
- 農(nóng)資袋子銷售合同范例
- 四年級數(shù)學思維訓練社團活動(素質(zhì)拓展)電子教案
- 金屬切削過程中的變形 revised課件
- 蒙古族文化課件
- 簡明燒傷健康量表
- 傳染病布氏菌病 課件
- 商業(yè)廣告設計課件
- 教會行政管理學課程教案
- SJG 44-2018 深圳市公共建筑節(jié)能設計規(guī)范-高清現(xiàn)行
- 2022年高考(全國甲卷)語文仿真模擬卷【含答案】
- _重大事故后果分析(精)
- 水泥攪拌樁施工監(jiān)理質(zhì)量控制要點
評論
0/150
提交評論