程序建立 fork,wait,waitpid

2021-08-14 13:12:38 字數 3412 閱讀 4343

1.pid_t fork();

(1)當乙個程序呼叫了fork 以後,系統會建立乙個子程序.這個子程序和父程序不同的地方只有他的程序id 和父程序id,其他的都是一樣.就象符程序轉殖(clone)自己一樣.

(2)為了區分父程序和子程序,我們必須跟蹤fork 的返回值. 當fork 掉用失敗的時候(記憶體不足或者是使用者的最大程序數已到)fork 返回-1,否則fork 的返回值有重要的作用.對於父程序fork 返回子程序的id,而對於fork 子程序返回0.我

們就是根據這個返回值來區分父子程序的.

(3)一旦子程序被建立,父子程序一起從fork 處繼續執行,相互競爭系統的資源.有時候我們希望子程序繼續執行,而父程序阻塞直

到子程序完成任務.這個時候我們可以呼叫wait 或者waitpid 系統呼叫.

vfork(建立乙個新的程序)

相關函式

wait,execve

表頭檔案

#include

定義函式

pid_t vfork(void);

函式說明

vfork()會產生乙個新的子程序,其子程序會複製父程序的資料與堆疊空間,並繼承父程序的使用者**,組**,環境變數、已開啟的檔案**、工作目錄和資源限制等。linux 使用copy-on-write(cow)技術,只有當其中一程序試圖修改欲複製的空間時才會做真正的複製動作,由於這些繼承的資訊是複製而來,並非指相同的記憶體空間,因此子程序對這些變數的修改和父程序並不會同步。此外,子程序不會繼承父程序的檔案鎖定和未處理的訊號。注意,linux不保證子程序會比父程序先執行或晚執行,因此編寫程式時要留意

死鎖或競爭條件的發生。

返回值如果vfork()成功則在父程序會返回新建立的子程序**(pid),而在新建立的子程序中則返回0。如果vfork 失敗則直接返回-1,失敗原因存於errno中。

錯誤**

eagain 記憶體不足。enomem 記憶體不足,無法配置核心所需的資料結構空間。

範例#include

main()

else}執行

this is the parent process

this is the child process

wait(等待子程序中斷或結束)

表頭檔案

#include

#include

定義函式

pid_t wait (int * status);

函式說明

wait()會暫時停止目前程序的執行,直到有訊號來到或子程序結束。如果在呼叫wait()時子程序已經結束,則wait()會立即返回子程序結束狀態值。子程序的結束狀態值會由引數status 返回,而子程序的程序識別碼也會一快返回。如果不在意結束狀態值,則

引數status可以設成null。子程序的結束狀態值請參考waitpid()。

返回值如果執行成功則返回子程序識別碼(pid),如果有錯誤發生則返回-1。失敗原因存於errno中。

waitpid(等待子程序中斷或結束)

表頭檔案

#include

#include

定義函式

pid_t waitpid(pid_t pid,int * status,int options);

函式說明

waitpid()會暫時停止目前程序的執行,直到有訊號來到或子程序結束。如果在呼叫wait()時子程序已經結束,則wait()會立即返回子程序結束狀態值。子程序的結束狀態值會由引數status返回,而子程序的程序識別碼也會一快返回。如果不在意結束狀態值,則引數status可以設成null。引數pid為欲等待的子程序識別碼,其他數值意義如下:

pidpid=-1 等待任何子程序,相當於wait()。

pid=0 等待程序組識別碼與目前程序相同的任何子程序。

pid>0 等待任何子程序識別碼為pid的子程序。

引數option可以為0 或下面的or 組合

wnohang 如果沒有任何已經結束的子程序則馬上返回,不予以等待。

wuntraced 如果子程序進入暫停執**況則馬上返回,但結束狀態不予以理會。

子程序的結束狀態返回後存於status,底下有幾個巨集可判別結束情況

wifexited(status)如果子程序正常結束則為非0值。

wexitstatus(status)取得子程序exit()返回的結束**,一般會先用wifexited 來判斷是否正常結束才能使用此巨集。

wifsignaled(status)如果子程序是因為訊號而結束則此巨集值為真

wtermsig(status)取得子程序因訊號而中止的訊號**,一般會先用wifsignaled 來判斷後才使用此巨集。

wifstopped(status)如果子程序處於暫停執**況則此巨集值為真。一般只有使用wuntraced 時才會有此情況。

wstopsig(status)取得引發子程序暫停的訊號**,一般會先用wifstopped 來判斷後才使用此巨集。

返回值如果執行成功則返回子程序識別碼(pid),如果有錯誤發生則返回-1。失敗原因存於errno中。

例子:#include

c**  

"font-size: small;">#include 

#include 

#include 

#include 

#include 

#include 

int main(void)  else

if (child == 0)   

while (((child = waitpid(getpid(),&status,0)) == -1)&(errno == eintr));  

if (child == -1)  

printf("wait error:%s\n", strerror(errno));  

else

if (!status)  

printf("child %ld terminated normally return status is zero\n",  

child);  

else

if (wifexited(status))  

printf("child %ld terminated normally return status is %d\n",  

child, wexitstatus(status));  

else

if (wifsignaled(status));  

printf("child %ld terminated due to signal %d znot caught\n",  

child, wtermsig(status));  

getchar();  

return (exit_success);  

}  

程序建立,程序等待,程序終止

1 程序建立,2 程序等待,3 程序終止 程序建立被定義為通過父程序建立子程序的過程。fork函式 函式原型 pid t fork void 特點 1.fork函式呼叫一次,返回兩次兩次返回值得區別分別是子程序當中的返回值為0,父程序當中的返回值為新建子程序的id 將id返回給父程序的原因是沒有函式...

程序排程之建立程序

do fork struct pid pid alloc pid struct pid pid kmem cache alloc pid cachep,gfp kernel 分配pid結構體空間 nr alloc pidmap current nsproxy pid ns 分配pid程序號 pid ...

程序管理3 程序建立

許多作業系統都提供了產生 spawn 程序的機制,首先在新的位址空間裡建立程序,讀入可執行檔案,最後開始執行。unix採用了與眾不同的實現方式,它把上述步驟分解到兩個單獨的函式中去執行 fork 和exec 把這兩個函式組合起來使用和其他系統使用的單一函式效果相似。1 寫時拷貝 傳統的fork 會直...