版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
進程進程進程控制的相關函數(shù)進程的創(chuàng)建派生進程:fork(),vfork();創(chuàng)建執(zhí)行其他程序的進程:exec();(選學)Linux系統(tǒng)特有的調用:__clone();(選學)進程的等待wait(),waitpid();進程的終止exit(),atexit(),on_exit(),abort(),_exit();其他函數(shù)system()(選學)
,getpid()。進程的創(chuàng)建fork()函數(shù)#include<sys/types.h>#include<unistd.h>pid_tfork(void);fork在英文中是“分叉”的意思。一個進程在運行中,如果使用了fork
,就產生了另一個進程,于是進程就“分叉”了。當前進程為父進程,通過fork()會產生一個子進程。對于父進程,返回子程序的進程號,而對于子程序則返回0,這就是fork函數(shù)的特點“調用一次,返回兩次”,出錯則返回-1。fork函數(shù)是Unix系統(tǒng)最杰出的成就之一。進程的創(chuàng)建fork函數(shù)實例以及說明:因父進程和子進程的運行無關,父進程或子進程返回的順序隨機的,因此運行結果不唯一。vfork()函數(shù)以及實例vfork創(chuàng)建新進程的主要目的在于用exec函數(shù)執(zhí)行另外的程序,實際上,在沒調用exec或exit之前子進程的運行中是與父進程共享數(shù)據(jù)段的。在vfork調用中,子進程先運行,父進程掛起,直到子進程調用exec或exit,在這以后,父子進程的執(zhí)行順序不再有限制。進程的創(chuàng)建fork函數(shù)實例以及說明:因父進程和子進程的運行無關,父進程或子進程返回的順序隨機的,因此運行結果不唯一。vfork()函數(shù)以及實例vfork創(chuàng)建新進程的主要目的在于用exec函數(shù)執(zhí)行另外的程序,實際上,在沒調用exec或exit之前子進程的運行中是與父進程共享數(shù)據(jù)段的。在vfork調用中,子進程先運行,父進程掛起,直到子進程調用exec或exit,在這以后,父子進程的執(zhí)行順序不再有限制。進程的創(chuàng)建fork運行結果vfork運行結果進程的創(chuàng)建fork運行結果vfork運行結果進程的創(chuàng)建(選學)exec()函數(shù)族用fork創(chuàng)建子進程后執(zhí)行的是和父進程相同的程序(但有可能執(zhí)行不同的代碼分支),子進程往往要調用一種exec函數(shù)以執(zhí)行另一個程序。當進程調用一種exec函數(shù)時,該進程的用戶空間代碼和數(shù)據(jù)完全被新程序替換,從新程序的啟動例程開始執(zhí)行。調用exec并不創(chuàng)建新進程,所以調用exec前后該進程的id并未改變。進程的創(chuàng)建(選學)其實有六種以exec開頭的函數(shù),統(tǒng)稱exec函數(shù):#include<unistd.h>intexecl(constchar*path,constchar*arg,...);intexeclp(constchar*file,constchar*arg,...);intexecle(constchar*path,constchar*arg,...,char*constenvp[]);intexecv(constchar*path,char*constargv[]);intexecvp(constchar*file,char*constargv[]);intexecve(constchar*path,char*constargv[],char*constenvp[]);進程的創(chuàng)建(選學)這些函數(shù)如果調用成功則加載新的程序從啟動代碼開始執(zhí)行,不再返回,如果調用出錯則返回-1,所以exec函數(shù)只有出錯的返回值而沒有成功的返回值。在exec函數(shù)族中,后綴l、v、p、e添加到exec后,所指定的函數(shù)將具有某種操作能力有后綴:p(path)時,函數(shù)可以利用DOS的PATH變量查找子程序文件。假如你希望執(zhí)行命令/bin/cat/etc/passwd/etc/group(通過cat命令查看/etc/passwd和/etc/group的內容)進程的創(chuàng)建(選學)l(list)時,希望接收以逗號分隔的參數(shù)列表,列表以NULL指針作為結束標志。execl("/bin/cat","/etc/passed","/etc/group",NULL);v(vector)時,希望接收到一個以NULL結尾的字符串數(shù)組的指針。char*argv[]={"/bin/cat","/etc/passed","/etc/group",NULL}execv("/bin/cat",argv);e(environment)時,函數(shù)傳遞參數(shù)envp,允許改變子進程的環(huán)境,無后綴e時,子進程使用當前程序的環(huán)境。envp也是一個以NULL結尾的字符串數(shù)組指針。進程的創(chuàng)建(選學)execl和execlp完全相同,execv和execvp完全相同。execl()和execv()要求提供可執(zhí)行文件的絕對或相對路徑名,而execlp()和execvp()使用$PATH環(huán)境變量查找path。進程的創(chuàng)建(選學)一個完整的例子#include<unistd.h>#include<stdlib.h>intmain(void){ execlp("ps","ps","-o", "pid,ppid,pgrp,session,tpgid,comm",NULL); perror("execps");exit(1);}[root@localhostch06]#./execlpPIDPPIDPGRPSESSTPGIDCOMMAND91259122 9125 91259937 bash99379125 9937 91259937 ps進程的創(chuàng)建(選學)由于exec函數(shù)只有錯誤返回值,只要返回了一定是出錯了,所以不需要判斷它的返回值,直接在后面調用perror即可。注意在調用execlp時傳了兩個"ps"參數(shù),第一個"ps"是程序名,execlp函數(shù)要在PATH環(huán)境變量中找到這個程序并執(zhí)行它,而第二個"ps"是第一個命令行參數(shù),execlp函數(shù)并不關心它的值,只是簡單地把它傳給ps程序,ps程序可以通過main函數(shù)的argv[0]取到這個參數(shù)。調用exec后,原來打開的文件描述符仍然是打開的。利用這一點可以實現(xiàn)I/O重定向。實例execve.c進程的創(chuàng)建(選學)Linux特有的調用——cloneclone是Linux2.0以后才具備的新功能,它較fork更強(可認為fork是clone要實現(xiàn)的一部分),可以使得創(chuàng)建的子進程共享父進程的資源,并且要使用此函數(shù)必須在編譯內核時設置clone_actually_works_ok選項。clone函數(shù)的原型為:#inlude<sched.h>intclone(int(*fn)(void*),void*child_stack,intflags,void*arg);此函數(shù)返回創(chuàng)建進程的PID,函數(shù)中的flags標志用于設置創(chuàng)建子進程時的相關選項,具體含義如下表:進程的創(chuàng)建(選學)標志含義CLONE_PARENT創(chuàng)建的子進程的父進程是調用者的父進程,新進程與創(chuàng)建它的進程成了“兄弟”而不是“父子”CLONE_FS子進程與父進程共享相同的文件系統(tǒng),包括root、當前目錄、umaskCLONE_FILES子進程與父進程共享相同的文件描述符(filedescriptor)表CLONE_NEWNS在新的namespace啟動子進程,namespace描述了進程的文件hierarchyCLONE_SIGHAND子進程與父進程共享相同的信號處理(signalhandler)表CLONE_PTRACE若父進程被trace,子進程也被traceCLONE_VFORK父進程被掛起,直至子進程釋放虛擬內存資源CLONE_VM子進程與父進程運行于相同的內存空間CLONE_PID子進程在創(chuàng)建時PID與父進程一致CLONE_THREADLinux2.4中增加以支持POSIX線程標準,子進程與父進程共享相同的線程群進程等待在多進程處理時,用戶可能需要用到有關進程等待的操作。這種等待可以是進程組成員間的等待,也可以是父進程對子進程的等待。例如,當一個進程結束時,Linux系統(tǒng)將產生一個SIGCHLD信號通知其父進程。在父進程未查詢子進程結束的原因時,該子進程雖然停止了,但并未完全結束。此時該子進程被稱為僵尸進程(zombieprocess)這時的處理方法之一就是使用進程等待的系統(tǒng)調用wait
和waitpid。進程等待wait()函數(shù)#include<sys/types.h>#include<sys/wait.h>pid_twait(int*status);進程一旦調用了wait,就立即阻塞自己,由wait()函數(shù)分析是否當前的某個子進程已經退出,如果讓它找到了這樣一個已經變成僵尸的子進程,wait就會收集這個子進程的信息,并把它徹底銷毀后返回;如果沒有找到這樣一個子進程,wait就會一直阻塞在這里,直到有一個出現(xiàn)為止??烧J為wait()系統(tǒng)調用的作用就是負責回收僵尸進程。進程等待因為在下列兩個事件都已經發(fā)生的情況下進程才會完全終止:(1)進程自己已經退出(或已經被一個信號殺死)(2)它的父進程已經執(zhí)行了WAIT系統(tǒng)調用以觀察發(fā)生了什么。如果已經退出或被殺死而它的父進程還沒有為它執(zhí)行WAIT的進程將進入某種掛起狀態(tài),有時被稱為僵死狀態(tài)(ZombieState),這種進程不再參與調度,它的報警時鐘被關閉,但它仍將留在進程表中,它的內存被釋放。僵死是一種臨時狀態(tài),很少會持續(xù)較長的時間,當父進程最后執(zhí)行WAIT時,將釋放進程表項,并通知文件系統(tǒng)和內核。進程等待對于參數(shù)status是一個指向int型的變量,用來保存子進程退出時的狀態(tài)(例如子進程中有exit(2009)或return(2009),那么這個變量里的某些二進制位存放的就是2009,也就是子進程的返回值),但如果我們對這個子進程是如何死掉的毫不在意,只想把這個僵尸進程消滅掉,(事實上絕大多數(shù)情況下,我們都會這樣想),我們就可以設定這個參數(shù)為NULL,就象下面這樣:pid=wait(NULL);如果成功,wait會返回被收集的子進程的進程ID,如果調用進程沒有子進程,調用就會失敗,此時wait返回-1,同時errno被置為ECHILD。進程等待Wati()函數(shù)實例:wait1.c編譯并運行: $gccwait1.c-owait1 $./wait1 Thisischildprocesswithpidof1508 Icatchedachildprocesswithpidof1508可以明顯注意到,在第2行結果打印出來前有10秒鐘的等待時間,這就是我們設定的讓子進程睡眠的時間,只有子進程從睡眠中蘇醒過來,它才能正常退出,也就才能被父進程捕捉到。其實這里我們不管設定子進程睡眠的時間有多長,父進程都會一直等待下去。進程等待如果參數(shù)status的值不是NULL,wait就會把子進程退出時的狀態(tài)取出并存入其中,這是一個整數(shù)值,指出了子進程是正常退出還是被非正常結束的(一個進程也可以被其他進程用信號結束),以及正常結束時的返回值,或被哪一個信號結束的等信息。由于這些信息被存放在一個整數(shù)的不同二進制位中,所以用常規(guī)的方法讀取會非常麻煩,人們就設計了一套專門的宏(macro)來完成這項工作,下面我們來學習一下其中最常用的兩個:進程等待1、WIFEXITED(status)這個宏用來指出子進程是否為正常退出的,如果是,它會返回一個非零值。請注意,雖然名字一樣,這里的參數(shù)status并不同于wait唯一的參數(shù)--指向整數(shù)的指針status,而是那個指針所指向的整數(shù),切記不要搞混了。2、WEXITSTATUS(status)當WIFEXITED返回非零值時,我們可以用這個宏來提取子進程的返回值,如果子進程調用exit(5)退出,WEXITSTATUS(status)就會返回5;如果子進程調用exit(7),WEXITSTATUS(status)就會返回7。請注意,如果進程不是正常退出的,也就是說,WIFEXITED返回0,這個值就毫無意義進程等待wait2.c實例。編譯并運行:[root@localhostch06]#gcc-owait2wait2.c[root@localhostch06]#./wait2Thisischildprocesswithpidof12668.thechildprocess12668exitnormally.thereturncodeis3.父進程準確捕捉到了子進程的返回值3,并把它打印了出來。進程等待waitpid()函數(shù)waitpid()
系統(tǒng)調用在Linux函數(shù)庫中的原型是: #include<sys/types.h> /#include<sys/wait.h> pid_twaitpid(pid_tpid,int*status,intoptions);從本質上講,系統(tǒng)調用waitpid和wait的作用是完全相同的,但waitpid多出了兩個可由用戶控制的參數(shù)pid和options,從而為我們編程提供了另一種更靈活的方式。下面我們就來詳細介紹一下這兩個參數(shù):進程等待pid參數(shù)pid>0時,只等待進程ID等于pid的子進程,不管其它已經有多少子進程運行結束退出了,只要指定的子進程還沒有結束,waitpid就會一直等下去。pid=-1時,等待任何一個子進程退出,沒有任何限制,此時waitpid和wait的作用一模一樣。pid=0時,等待同一個進程組中的任何子進程,如果子進程已經加入了別的進程組,waitpid不會對它做任何理睬。pid<-1時,等待一個指定進程組中的任何子進程,這個進程組的ID等于pid的絕對值。進程等待options參數(shù)options提供了一些額外的選項來控制waitpid,目前在Linux中只支持WNOHANG和WUNTRACED兩個選項,這是兩個常數(shù),可以用"|"運算符把它們連接起來使用,比如:ret=waitpid(-1,NULL,WNOHANG|WUNTRACED);
如果我們不想使用它們,也可以把options設為0,如:ret=waitpid(-1,NULL,0);如果使用了WNOHANG參數(shù)調用waitpid,即使沒有子進程退出,它也會立即返回,不會像wait那樣永遠等下去。而WUNTRACED參數(shù),由于涉及到一些跟蹤調試方面的知識,加之極少用到,這里就不多講。進程等待Waitpid()函數(shù)實例編譯并運行:
$gccwaitpid.c-owaitpid $./waitpid Nochildexited
Nochildexited Nochildexited
Nochildexited
Nochildexited
Nochildexited
Nochildexited
Nochildexited
Nochildexited
Nochildexited successfullygetchild1526父進程經過10次失敗的嘗試之后,終于收集到了退出的子進程。進程等待父進程調用wait或waitpid時可能會:阻塞(如果它的所有子進程都還在運行)。帶子進程的終止信息立即返回(如果一個子進程已終止,正等待父進程讀取其終止信息)。出錯立即返回(如果它沒有任何子進程)。這兩個函數(shù)的區(qū)別是:如果父進程的所有子進程都還在運行,調用wait將使父進程阻塞,而調用waitpid時如果在options參數(shù)中指定WNOHANG可以使父進程不阻塞而立即返回0。wait等待第一個終止的子進程,而waitpid可以通過pid參數(shù)指定等待哪一個子進程。進程的終止進程結束可通過相應的函數(shù)實現(xiàn):voidexit(intstatus);void_exit(intstatus);終止正在運行的程序,關閉所有被該文件打開的文件描述符_exit與exit不同的是可以關閉一些Linux下特有的退出句柄。intatexit(void(*function)(void));用于注冊一個不帶參數(shù)也沒有返回值的函數(shù)以供程序正常退出時被調用。參數(shù)function是指向所調用程序的文件指針。調用成功返回0,否則返回-1,并將errno設置為相應值進程的終止inton_exit(void(*function)(int,void*),void*arg);作用與atexit類似,不同是其注冊的函數(shù)具有參數(shù),退出狀態(tài)和參數(shù)arg都是傳遞給該函數(shù)使用。voidabort(void);用來發(fā)送一個SIGABRT信號,該信號將使當前進程終止。voidassert(intexpression);先計算表達式
expression,如果其值為0,那么它先向stderr打印一條出錯信息,然后通過調用abort來終止程序運行。常用來檢測某些參數(shù)是否有不當情況出現(xiàn),并在不當情況發(fā)生時以結束進程作為相應處理。進程的終止atexit實例assert實例system函數(shù)(選學)system函數(shù)是一個和操作系統(tǒng)緊密相關的函數(shù)。用戶可以使用它在自己的程序中調用系統(tǒng)提供的各種命令。 system函數(shù)的說明如下:#include<stdlib.h>intsystem(constchar*cmdstring);參數(shù)cmdstring是一個字符串指針。如果cmd是一個空指針,則僅僅當命令處理程序可用時,system返回非0值。system函數(shù)(選學)因為system在其實現(xiàn)中調用了fork,exec和waitpid,因此有三種返回值:1)如果fork失敗或者waitpid返回除EINTR之外的出錯,則system返回-1,而且errno中設置了錯誤類型2).如果exec失敗(表示不能執(zhí)行shell),則其返回值如同shell執(zhí)行了exit(127)一樣。3).否則所有三個函數(shù)(fork,exec和waitpid)都執(zhí)行成功,并且system的返回值是shell的終止狀態(tài),其格式已經在waitpid中說明。system函數(shù)(選學)如果一
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
- 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2024-2030年中國果醬行業(yè)市場規(guī)模調研及前景趨勢預測報告
- 2024-2030年中國服裝吊牌行業(yè)市場競爭策略及發(fā)展趨勢預測報告
- 2024-2030年中國智慧園區(qū)行業(yè)發(fā)展模式規(guī)劃分析報告
- 2024-2030年中國明焰窯爐生產線項目可行性研究報告
- 康復中心患者滿意度調查制度
- 老年醫(yī)療服務制度改革建議
- 急救醫(yī)療服務質量標準
- 幼兒園音樂活動游戲化的研究心得體會
- 電梯運營公司應急救援方案制定
- 形體體型評估課程設計
- 監(jiān)理公司各部門職責
- 253種中藥材粉末顯微鑒別主要特征
- 論辛棄疾詞作的愁情主題及其審美價值
- 新形勢下我國保險市場營銷的現(xiàn)狀、問題及對策
- LTE無線網絡優(yōu)化PPT課件
- 動態(tài)血壓監(jiān)測在社區(qū)高血壓患者管理的意義
- 管道中英文對照表
- 240燈控臺_說明書
- 新形勢下加強市場監(jiān)管局檔案管理工作的策略
- 例行檢查和確認檢驗程序
- 上海旅游資源基本類型及其旅游區(qū)布局特點(共5頁)
評論
0/150
提交評論