《linux軟件工程師(C語言)實用教程》第6章.ppt_第1頁
《linux軟件工程師(C語言)實用教程》第6章.ppt_第2頁
《linux軟件工程師(C語言)實用教程》第6章.ppt_第3頁
《linux軟件工程師(C語言)實用教程》第6章.ppt_第4頁
《linux軟件工程師(C語言)實用教程》第6章.ppt_第5頁
已閱讀5頁,還剩48頁未讀, 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

1、第 6 章,進程控制,2,本章重點,進程的基本概念及進程的結構 Linux環(huán)境下進程的相關函數的應用 守護進程的概念、啟動和建立 進程控制程序的編寫,3,6.1 進程簡介,進程是一個程序的一次執(zhí)行的過程。 在Linux環(huán)境下,每個正在運行的程序都稱為進程。 每個進程包含進程標識符及數據,這些數據包含進程變量、外部變量及進程堆棧等。 1. 進程與程序 由于一個進程對應一個程序的執(zhí)行,但進程不等同于程序。因為程序是靜態(tài)的概念,進程是動態(tài)的概念。 進程是程序執(zhí)行的過程,包括了動態(tài)創(chuàng)建、調度和消亡的整個過程。進程是程序執(zhí)行和資源管理的最小單位。 對系統(tǒng)而言,當用戶在各級系統(tǒng)中鍵入命令執(zhí)行一個程序的時候

2、,它將啟動一個進程,因此,一個程序可以對應多個進程。,4,6.1 進程簡介,2. Linux環(huán)境下的進程管理 Linux環(huán)境下的進程管理包括啟動進程和調度進程。 啟動進程有兩種主要途徑:手工啟動和調度啟動。 (1)手工啟動又可分為前臺啟動和后臺啟動。 前臺啟動:是手工啟動一個進程的最常用方式。一般地,當用戶輸入一個命令時,就已經啟動了一個進程,并且是一個前臺的進程。 后臺啟動:往往是在該進程非常耗時,且用戶也不急著需要結果的時候啟動。一般地,當用戶輸入一個命令結尾加上一個“ 函數的使用為: execv(/bin/ps,arg); 參考程序: #include /*文件預處理,包含標準輸入輸出庫

3、*/ #include /*文件預處理,包含getpid、getppid函數庫*/ int main () /*C程序的主函數,開始入口*/ char *arg=ls,-al,NULL; execv(/bin/ls,arg); return 1; ,15,6.2.2 進程創(chuàng)建,思考題2:execlp 函數的應用,要在程序中執(zhí)行命令:ps -ef,命令ps在/bin目錄下。在這一函數中,參數l表示命令或參數逐個列舉,參數p為文件查找方式(不需要給出路徑)。因而此函數的調用形式為: execlp(ps,ps,-ef,NULL); 請編寫一程序進行調試。 思考題3:execl 函數的應用,要在程序中

4、執(zhí)行命令:ps -ef,命令ps在/bin目錄下。在這一函數中,參數l表示命令或參數逐個列舉,文件需給定路徑。因而此函數的調用形式為:execl(/bin/ps,ps,-ef,NULL); 請編寫一程序進行調試。,16,6.2.2 進程創(chuàng)建,2. system函數 system函數是一個和操作系統(tǒng)緊密相關的函數。用戶可以使用它在自己的程序中調用系統(tǒng)提供的各種命令。 使用時不需要預處理頭文件“unistd.h”。 例6-3:設計一個程序,要求測試到LUPA社區(qū)的網絡連通狀況。 編輯源程序代碼:,17,6.2.2 進程創(chuàng)建,編譯、運行程序,系統(tǒng)會出現運行結果,先顯示Linux系統(tǒng)分配的進程號(PI

5、D),接著運行ping程序,創(chuàng)建新的進程 。 再打開一個終端,用ps查看原進程和新創(chuàng)建進程的進程號(PID) 。 可以看到,原來6-3的進程 (PID)值和新進程的父進程號(PPID)值相同,在新進程創(chuàng)建后,原來的進程并沒有終止。,注意:在第二個終端的時候,第一個終端中的ping不能結束。,18,6.2.2 進程創(chuàng)建,system函數說明,思考題:如何使用前面的exec函數族中的函數,調用此例中的系統(tǒng)命令“ping ”?,19,6.2.2 進程創(chuàng)建,3. fork函數 使用fork函數創(chuàng)建進程時,新的進程叫子進程,原來調用fork函數的進程則稱為父進程。 子進程會復制父進程的數據和堆??臻g,并

6、繼承父進程的用戶代碼、組代碼、環(huán)境變量、已經打開的文件代碼、工作目錄及資源限制等,但是子進程和父進程使用不同的內存空間。,20,6.2.2 進程創(chuàng)建,例6-4:設計一個程序,要求先顯示當前目錄下的文件信息,然后測試到LUPA社區(qū)的網絡連通狀況。 編輯源程序代碼,21,6.2.2 進程創(chuàng)建,編譯、運行程序,觀察結果。 可以看到,使用fork函數創(chuàng)建了一個子進程,子進程的返回值是0,父進程的返回值是子進程的進程號(PID) 。而子進程的父進程號(PPID)和父進程的進程號(PID)相同。 可見,子進程由父進程派生出來。,注意:fork函數使用一次就創(chuàng)建一個進程,所以若把fork函數放在if els

7、e判斷語句或for循環(huán)語句中則要小心,不能多次使用fork函數。,如: void main() for(;)fork(); ,22,6.2.2 進程創(chuàng)建,sleep函數說明,fork函數說明,23,6.2.2 進程創(chuàng)建,思考題:此例中,為什么用sleep等待10秒鐘? 思考題:設計一個程序,在子進程中調用函數execl(/bin/ps,ps,-ef,NULL),而在父進程中調用函數execle(/bin/env,env,NULL,envp),其中有定義:char *envp=PATH=/tmp,USER=liu,NULL; 請編寫并進行調試。,24,6.2.3 進程終止,濫用fork函數會占滿

8、系統(tǒng)進程,而且子進程與父進程使用不同的內存空間,不斷產生子進程,也可能讓系統(tǒng)資源消耗殆盡。 Linux環(huán)境下c終止進程主要用exit和_exit函數。 例6-5:設計一個程序,要求子進程和父進程都在顯示輸出一些文字后分別用exit和_exit函數終止進程。 編輯源程序代碼:,觀察結果可以看出,調用exit函數時,緩沖區(qū)中的記錄能正常輸出;而調用_exit時,緩沖區(qū)中的記錄無法輸出。,25,6.2.3 進程終止,_exit()函數作用:直接使進程停止運行,清除其使用的內存空間,并清除其在內核中的各種數據結構; exit()函數則在執(zhí)行退出之前加了若干道工序,exit函數在調用exit系統(tǒng)之前要查

9、看文件的打開情況,把文件緩沖區(qū)中的內容寫回文件。,26,6.2.3 進程終止,exit函數說明,_exit函數說明,27,6.2.4 僵尸進程,一個僵尸進程(zombie),是指已終止運行,但尚末被清除的進程,又稱為過渡進程。 當使用fork函數創(chuàng)建子進程時,由于子進程有可能比父進程晚終止,父進程終止后,子進程還沒終止,子進程就成了僵尸進程。為避免這種情況,可以在父進程中調用wait或waitpid函數。 wait函數是用于使父進程阻塞,直到一個子進程終止或者該進程接到了一個指定的信號為止。 waitpid的作用和wait一樣,但它并不一定要等待第一個終止的子進程,它還有若干選項,也能支持作業(yè)

10、控制。 實際上wait函數只是waitpid函數的一個特例,在Linux內部實現wait函數時直接調用的就是waitpid函數。,28,6.2.4 僵尸進程,例6-6:設計一個程序,要求復制進程,子進程顯示自己的進程號(PID)后暫停一段時間,父進程等待子進程正常結束,打印顯示等待的進程號(PID)和等待的進程退出狀態(tài)。 流程圖:,29,6.2.4 僵尸進程,編輯源程序代碼:,此例中的子進程運行時間,明顯比父進程時間長。為了避免子進程成為僵尸進程,父進程調用wait,阻塞父進程的運行,等待子進程正常結束,父進程才繼續(xù)運行,直到正常結束。,30,6.2.4 僵尸進程,wait函數說明,31,6.

11、2.4 僵尸進程,例6-7:設計一個程序,要求用戶可以選擇是否復制進程,子進程模仿思科(Cisco)1912交換機的開機界面,以命令行的方式讓用戶選擇進入,父進程判斷子進程是否正常終止。 流程圖:,32,6.2.4 僵尸進程,編輯源程序代碼:,33,6.2.4 僵尸進程,編譯、運行程序,提示是否復制進程,先選擇“2.不復制進程”,此時沒有產生子進程,返回值為“0” 。 再次運行程序后,選擇“1.復制進程”,此時產生子進程,子進程的功能是模擬交換機的開機界面,提示選擇畫面,這兒選擇0,進入子程序display0,等待子程序運行終止后,返回值為“1”,父進程才終止。 修改程序:不用waitpid函

12、數。 再次運行程序后,選擇“1.復制進程”,這時候父進程沒有等待子進程,也就是在模擬顯示完交換機的開機界面后,根本沒來得及輸入選擇,父進程就終止了,子進程就變成了僵尸進程。,此例可以看出,在沒有語法、語義等錯誤的情況下,程序還是沒有完成設計要求??梢?,在多進程程序設計時,除了養(yǎng)成使用完后就終止的良好習慣,還要讓子進程工作完成后再終止,這個時候父進程就得靈活使用wait函數和waitpid函數。,34,6.2.4 僵尸進程,waitpid函數說明,35,6.3 Linux守護進程,守護進程(Daemon)是運行在后臺的一種特殊進程。 守護進程獨立于控制終端并且周期性地執(zhí)行某種任務或等待處理某些發(fā)

13、生的事件。 守護進程是一種很有用的進程。Linux的大多數服務器就是用守護進程實現的。 同時,守護進程完成許多系統(tǒng)任務。,36,6.3.1 守護進程及其特性,守護進程最重要的特性是后臺運行。 其次,守護進程必須與其運行前的環(huán)境隔離開來。這些環(huán)境包括未關閉的文件描述符,控制終端,會話和進程組,工作目錄以及文件創(chuàng)建掩碼等。這些環(huán)境通常是守護進程從執(zhí)行它的父進程(特別是shell)中繼承下來的。 最后,守護進程的啟動方式有其特殊之處。它可以在Linux系統(tǒng)啟動時從啟動腳本/etc/rc.d中啟動,也可以由作業(yè)規(guī)劃進程crond啟動,還可以由用戶終端(通常是shell)執(zhí)行。,37,6.3.1 守護進

14、程及其特性,通過ps aux命令可查看Linux環(huán)境下的守護進程: Init系統(tǒng)守護進程:它是進程1,負責啟動各運行層次特定的系統(tǒng)服務。 Keventd守護進程:為在內核中運行計劃執(zhí)行的函數提供進程上下文。 Kswapd守護進程:也稱為頁面調出守護進程。它通過將臟頁面以低速寫到磁盤上從而使這些頁面在需要時仍可回收使用,這種方式支持虛存子系統(tǒng)。 bdflush和kupdated守護進程:Linux內核使用兩個守護進程bdflush和kupdated將調整緩存中的數據沖洗到磁盤上。當可用內存達到下限時,bdflush守護進程將臟緩沖區(qū)從緩沖池中沖洗到磁盤上,每隔一定時間間隔,kupdated守護進

15、程將臟頁面沖洗到磁盤上,以便在系統(tǒng)失效時減少丟失的數據。,38,6.3.1 守護進程及其特性,portmap端口映射守護進程:提供將RPC(遠程過程調用)程序號映射為網絡端口號的服務。 syslogd守護進程:可由幫助操作人員把系統(tǒng)消息記入日志的任何程序使用。 inetd守護進程(xinetd):它偵聽系統(tǒng)網絡接口,以便取得來自網絡的對各種網絡服務進程的請求。 nfsd、lockd、rpciod守護進程:提供對網絡文件系統(tǒng)(NFS)的支持。 cron守護進程:在指定的日期和時間執(zhí)行指定的命令。許多系統(tǒng)管理任務是由cron定期地執(zhí)行相關程序而實現的。 cupsd守護進程:是打印假脫機進程,它處理

16、對系統(tǒng)提出的所有打印請求。,注意:大多數守護進程都以超級用戶(用戶ID為0)特權運行。沒有一個守護進程具有控制終端,其終端名設置為問號(?)。,39,6.3.2 編寫守護進程的要點,40,6.3.2 編寫守護進程的要點,(1)創(chuàng)建子進程,終止父進程 pid=fork(); if(pid0) exit(0); /*終止父進程*/ (2)在子進程中創(chuàng)建新會話 setsid函數用于創(chuàng)建一個新的會話,并擔任該會話組的組長,其作用: 讓進程擺脫原會話的控制; 讓進程擺脫原進程組的控制; 讓進程擺脫原控制終端的控制。 而setsid函數能夠使進程完全獨立出來,從而脫離所有其他進程的控制。,41,6.3.2

17、 編寫守護進程的要點,(3)改變工作目錄 改變工作目錄的常見函數是chdir。 (4)重設文件創(chuàng)建掩碼 文件創(chuàng)建掩碼是指屏蔽掉文件創(chuàng)建時的對應位。 把文件創(chuàng)建掩碼設置為0,可以大大增強該守護進程的靈活性。 設置文件創(chuàng)建掩碼的函數是umask。,42,6.3.2 編寫守護進程的要點,(5)關閉文件描述符 通常按如下方式關閉文件描述符: for(i=0;iNOFILE;i+) close(i); 或者也可以用如下方式: for(i=0;iMAXFILE;i+) close(i);,43,6.3.3 守護進程的編寫,例6-8:設計兩個程序,主程序6-8.c和初始化程序init.c。要求主程序每隔十秒

18、鐘向/tmp目錄中的日志6-8.log報告運行狀態(tài)。初始化程序中的init_daemon函數負責生成守護進程。,44,6.3.3 守護進程的編寫,編輯源程序代碼:,注意:這里的fopen函數必須具有root權限。如果沒有root權限,可以看到守護進程的運行,但不會在文件里寫入任何字符。,45,6.3.3 守護進程的編寫,編譯、運行文件后,沒有任何提示,等待一段時間后,查看一下 6-8.log文件中有沒有文字寫入,輸入“tail -f /tmp/6-8.log”,顯示多條文字,從時間上看,說明守護進程在暗地里每隔10秒寫入一串字符。 用ps命令查看進程。 可見,6-8確實一直在運行,而且看到“?

19、”結合Linux環(huán)境下進程的知識,知道確實有了一個守護進程。,注意:父進程創(chuàng)建了子進程,而父進程又退出之后,此時該子進程就變成了“孤兒進程”。在Linux中,每當系統(tǒng)發(fā)現一個孤兒進程,就會自動由1號進程(也就是init進程)收養(yǎng)它,原先的子進程就會變成init進程的子進程了。,46,6.3.3 守護進程的編寫,setsid函數說明:,思考題: 此例中如果不先終止父進程,就調用setsid函數會發(fā)生什么?守護進程運行后,注消當前用戶后再登錄進去,守護進程還在運行嗎? 編寫一程序,要求運行后成為守護進程,每隔5分鐘修改一次本機的IP地址。,47,6.3.3 守護進程的編寫,例6-9:設計兩個程序,

20、要求運行后成為守護進程,守護進程又復制出一個子進程,守護進程和它的子進程都調用syslog函數,把結束前的狀態(tài)寫入系統(tǒng)日志文件。 流程圖:,48,6.3.3 守護進程的編寫,編輯源程序代碼:,注意:調用openlog、syslog函數,操作的系統(tǒng)日志文件“/var/log/message”,必須具有root權限。,49,6.3.3 守護進程的編寫,編譯、運行程序后,沒有任何提示,等待一段時間后,查看一下/var/log/messages文件中有沒有文字寫入,輸入“tail -f /var/log/messages”, 此時,顯示多條文字,說明守護進程通過系統(tǒng)日志管理服務,在暗地里寫入一串字符,

21、而且從時間上看出,第二子進程確實是在暫停5秒鐘后退出的。 用ps命令查看進程 。 可見,6-9確實一直在運行,而且看到“?”結合Linux環(huán)境下進程的知識,知道確實有了一個守護進程。,50,6.3.3 守護進程的編寫,openlog函數說明,syslog函數說明,思考題:編寫一程序,要求運行后成為守護進程,復制守護進程的子進程,子進程往某個文件里寫入字符串“測試守護進程”,守護進程的錯誤信息輸出到系統(tǒng)日志文件“/var/log/messages”,程序以普通用戶權限編譯后運行調試會有什么結果?請把產生守護進程的部分分割成獨立的程序文件。,51,思考與實驗,什么是進程?進程與作業(yè)有何區(qū)別? 進程啟動的方式有哪幾種? 用exec函數創(chuàng)建一個進程,顯示當前目錄下的文件信息。 execle函數的應用,要在程序執(zhí)行時設定環(huán)境變量,路徑為tmp,用戶為liu,執(zhí)行命令env時把這些環(huán)境變量傳遞給系統(tǒng),在這一函數中,參數e表示可傳遞新進程環(huán)境變量,參數l表

溫馨提示

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

評論

0/150

提交評論