實驗三進程的創建和簡單控制(學生_第1頁
實驗三進程的創建和簡單控制(學生_第2頁
實驗三進程的創建和簡單控制(學生_第3頁
實驗三進程的創建和簡單控制(學生_第4頁
實驗三進程的創建和簡單控制(學生_第5頁
已閱讀5頁,還剩4頁未讀 繼續免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

1、【精品文檔】如有侵權,請聯系網站刪除,僅供學習與交流實驗三 進程的創建和簡單控制(學生.精品文檔.實驗三 進程的創建和簡單控制實驗目的:1. 掌握進程的概念和進程的狀態,對進程有感性的認識;2. 掌握進程創建方法;3. 認識進程的并發執行,了解進程族之間各種標識及其存在的關系;4. 熟悉進程的創建、阻塞、喚醒、撤銷等控制方法。實驗內容:1. 了解有關Linux進程的屬性和進程的層次結構;2. 學習有關Linux的前臺和后臺進程;3. 學習有關Linux命令的順序執行和并發執行;4. 學習有關掛起和終止進程;5. 了解并發程序的不可確定性,進行簡單并發程序設計。實驗步驟:(一)Shell下的進程

2、控制1. 進入Linux系統。2. 用ps查看進程。a) linux的ps命令是用來監視系統進程和資源使用情況的命令,可顯示瞬間進程的動態。b) ps 的參數非常多,常用的參數有:i. -A 列出所有的進程;ii. -w 顯示加寬可以顯示較多的信息;iii. -au 顯示較詳細的信息;iv. -aux 顯示所有包含其他使用者的進程。3. 用kill終止某些進程。a) kill命令通過向進程發送指定的信號來結束進程。b) 先使用ps查到進程號,再使用kill殺出進程。4. 用pstree命令顯示系統中進程層次結構。a) pstree指令用ASCII字符顯示樹狀結構,清楚地表達進程間的相互關系。b

3、) 語法格式 pstree -acGhlnpuUV-H /(二)Linux簡單進程編程1. 理解系統調用fork()的使用。a) fork()會產生一個與父程序相同的子程序,唯一不同之處在于其進程號,如圖 1所示。圖 1 系統調用fork()b) 編輯下面的程序,要求實現父進程產生兩個子進程,父進程顯示字符“a”、兩個子進程,分別顯示字符“b”、“c” ,如圖 2所示。#includemain( )int p1,p2;while (p1=fork()=-1); /*父進程創建第一個進程,直到成功*/if(p1=0) /*0返回給子進程 1*/putchar(b);/*P1的處理過程*/ els

4、e /*正數返回給父進程(子進程號)*/while (p2=fork()=-1); /*父進程創建第二個進程,直到成功*/if(p2=0) /*0返回給子進程2*/putchar(c);/*P2的處理過程*/ elseputchar(a);/*P2創建完成后,父進程的處理過程*/ 圖 2系統調用 fork()的使用示例一思考:i. 編譯連接通過后,多次運行程序,觀察進程并發執行結果,并分析原因。原因:當程序并發執行時,系統處于一個復雜的動態組合狀態,各程序執行的相對速度不確定,這使得這些程序多次并發執行得到的結果不同,調度、執行的順序由系統決定。ii. 刪除語句,觀察輸出的內容,體會fork的

5、使用。提示:編譯和運行該程序,分析結果出現兩種輸出的原因。刪除語句后:思考的問題:1. 運行命令為什么是“./command”?將源文件保存為以.c為后綴名的文件,開始進行編譯$gcc -o XXX XXX.c 編譯成功完成后,在當前路徑下,生成一個名為XXX的文件然后執行 $./XXX 程序得以運行2. . 和 . 什么含義?.表示當前目錄,.表示上級目錄,即父目錄3. shell 提示為什么不換行?因為在輸出語句中沒有/n換行符。4. 輸出字母為什么和提示交錯?b,a,shell,c四個進程并發執行,執行先后順序由系統調度決定。所以當shell調度在c進程前時,會出現輸出字母和提示交錯的現

6、象。5. 管道什么含義?管道符,可以認為它是一根水管,連接輸入端和輸出端。a | b其中,| 就是管道符,將輸入端 a命令產生的數據傳給輸出端的b命令來處理6. ./f1|pstree|grep f1什么含義?將./f1產生的數據傳給pstree來處理,經過pstree處理后的數據再傳給grep f1來處理在運行f1文件的進程的樹結構中查找f1(?)7. 6中組合命令為什么沒有輸出?8. 如果想保留6中的./f1的輸出內容,該如何操作?進行重定向操作9. ./f1 運行結果為什么不一樣?每種結果的產生原因。有a,b,c三個并發進程,調度順序由系統決定bcabacabc10. ./f1|pstr

7、ee|grep f1運行結果為什么不一樣?截圖中四種結果的產生原因。由于并發進程的調度順序是由系統決定的,并且pstree顯示的是一剎那的進程,進程調度又是動態的。四種結果:無結果:可能三個進程調度已經結束或者還未開始調度:父進程已經結束,兩個子進程還在運行:父進程開始運行,子進程還未開始調度:兩個子進程還在運行(?)注意:./f1 |pstree |grep f1命令之間有空格。pstree 還可以加上參數,-up如:./f1 |pstree up |grep f1提示:用pstree觀察進程的父子關系,其中第二次不是錯誤,而是捕捉的時機,當時父進程已經結束,兩個子進程還在運行。擴展:修改代

8、碼,產生祖孫三代的進程。說明:三個fe和bash都是進程,彼此間也會產生影響。2. 將上述的輸出字符改為輸出較長的字符串,如圖 3所示。#includeint main( )int p1,p2;while (p1=fork()= -1);/*父進程創建第一個進程,直到成功*/if(p1=0)/*0返回給子進程 1*/printf(boyn);/*P1的處理過程*/else/*正數返回給父進程(子進程號)*/while (p2=fork()=-1);/*父進程創建第二個進程,直到成功*/if(p2 = 0) /*0返回給子進程2*/printf(daughtern); /*P2的處理過程*/el

9、seprintf(parentn);/*P2創建完成后,父進程的處理過程*/圖 3系統調用 fork()的使用示例二思考:i. 編譯連接通過后,多次運行程序,觀察進程并發執行結果:執行結果均為:ii. 如果多次運行輸出內容沒有變化,請分析原因:函數fork( )用來創建一個新的進程,該進程幾乎是當前進程的一個完全拷貝,所以多次運行輸出內容沒有變化iii. 并改寫原程序,延長每個進程的執行時間,再次觀察運行情況。延長執行時間后:輸出的時間間隔變長3. (選作)將上述的輸出字符改為多條輸出語句,如圖 4所示。#includemain( )int p1,p2;int i;while (p1=fork

10、()=-1); /*父進程創建第一個進程,直到成功*/if(p1=0) /*0返回給子進程 1*/for( i =0; i 1000; i+) /*P1的處理過程*/putchar(b); else /*正數返回給父進程(子進程號)*/while (p2=fork()=-1); /*父進程創建第二個進程,直到成功*/if(p2=0) /*0返回給子進程2*/for( i =0; i 1000; i+)putchar(c); /*P2的處理過程*/elsefor( i =0; i 1000; i+)putchar(a); /*P2創建完成后,父進程的處理過程*/圖 4 系統調用 fork()的使

11、用示例三思考:i. 編譯連接通過后,多次運行程序,觀察進程并發執行結果:ii. 如果多次運行輸出內容沒有變化,請分析原因。并改寫原程序,延長每個進程的執行時間,再次觀察運行情況。iii. 如果多次運行輸出內容發生變化,并分析原因。iv. 將進程放在后臺運行,用pstree觀察進程的宗族關系。v. 系統創建一個新進程(使用系統調用fork)與讓系統執行一個新程序(使用系統調用exec)有什么差異?4. 理解系統調用wait()、getpid()和getppid()的使用。程序代碼如圖5所示。#include #include #include #include #include #include

12、 #include int main()char buf100;pid_t cld_pid;int fd;if(fd=open(temp,O_CREAT|O_TRUNC|O_RDWR,S_IRWXU)=-1)printf(open error%d,errno);exit(1);strcpy(buf,This is parent process writen);if(cld_pid=fork()=0) /*這里是子進程執行的代碼*/strcpy(buf,This is child process writen);printf(This is child processn);sleep(1);pr

13、intf(My PID (child) is%dn,getpid(); /*打印出本進程的ID*/sleep(1); printf(My parent PID is %dn,getppid(); /*打印出父進程的ID*/sleep(1);write(fd,buf,strlen(buf);close(fd);exit(0);else /*這里是父進程執行的代碼*/wait(0); /*如果此處沒有這一句會如何?*/printf(This is parent processn);sleep(1);printf(My PID (parent) is %dn,getpid(); /*打印出本進程的I

14、D*/sleep(1);printf(My child PID is %dn,cld_pid); /*打印出子進程的ID*/sleep(1);write(fd,buf,strlen(buf);close(fd);return 0;圖5 系統調用wait()的使用思考:i. 編譯連接通過后,多次運行程序,觀察進程并發執行結果:多次執行:ii. 語句sleep(1);起什么作用?刪除所有sleep(1);語句,并觀察運行結果;讓函數滯留1秒。iii. 刪除wait(0);語句,并觀察運行結果,并請分析兩次結果不同的原因,理解wait的作用。Wait的作用:wait函數用于使父進程阻塞,直到一個子進

15、程結束兩次結果不同的原因:wait(0)一般是父進程用來等待子進程用的,用來防止子進程成為僵尸進程,0表示父進程不關心子進程的終止狀態。實現父子進程的同步。5. (不做)編寫程序創建子進程。父子進程分別打印自己和父進程的進程ID,要求每3秒鐘打印系統進程信息,重復5次后退出。父進程待子進程結束后退出。提示:i. 用系統調用getpid和getppid獲取進程ID;ii. 用系統調用fork進程創建;iii. 用系統調用wait控制父子進程同步;iv. 用庫函數system實現在一個進程內部運行另一個進程,即創建一個新進程;v. Shell命令/bin/ps作為system的字符串參數,實現打印系統進程信息。擴充:關于父子進程各自又再生成子進程的例子。#include #include #in

溫馨提示

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

評論

0/150

提交評論