07 多程序程式設計

2021-07-30 12:23:56 字數 3784 閱讀 8434

fork

wait

exit

execl

vfork

waitpid

return

system

例子:

main()

wait:等待程序;

waitpid:等待程序;

函式功能:

掛起呼叫它的程序,直到其子程序結束;

空;函式原型:

int wait( int *status ) ;

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

函式標頭檔案:

《sys/types.h》《sys/wait.h》

《sys/types.h》《sys/wait.h》

函式返回值:

成功:返回終止的那個子程序的id;失敗:返回-1;

waitpid的返回值比wait稍微複雜一些,一共有3種情況:  ● 當正常返回的時候,waitpid返**集到的子程序的程序id;

● 如果設定了選項wnohang,而呼叫中waitpid發現沒有已退出的子程序可收集,則返回0;  ● 如果呼叫中出錯,則返回-1,這時errno會被設定成相應的值以指示錯誤所在;當pid所指示的子程序不存在,或此程序存在,但不是呼叫程序的子程序,waitpid就會出錯返回,這時errno被設定為echild.。

函式引數:

用來儲存被收集程序退出時的一些狀態,它是乙個指向int型別的指標。但如果我們對這個子程序是如何死掉的毫不在意,只想把這個殭屍程序消滅掉,(事實上絕大多數情況下,我們都會這樣想),我們就可以設定這個引數為null,就象下面這樣:pid = wait(null);

pid:從引數的名字pid和型別pid_t中就可以看出,這裡需要的是乙個程序id。但當pid取不同的值時,在這裡有不同的意義。pid>0時,只等待程序id等於pid的子程序,不管其它已經有多少子程序執行結束退出了,只要指定的子程序還沒有結束,waitpid就會一直等下去。pid=-1時,等待任何乙個子程序退出,沒有任何限制,此時waitpid和wait的作用一模一樣。pid=0時,等待同乙個程序組中的任何子程序,如果子程序已經加入了別的程序組,waitpid不會對它做任何理睬。pid《-1時,等待乙個指定程序組中的任何子程序,這個程序組的id等於pid的絕對值。options: options提供了一些額外的選項來控制waitpid,目前在linux中只支援wnohang和wuntraced兩個選項,這是兩個常數,可以用」|」運算子把它們連線起來使用;比如:ret=waitpid(-1,null,wnohang | wuntraced); 如果我們不想使用它們,也可以把options設為0,如: ret=waitpid(-1,null,0);如果使用了wnohang引數呼叫waitpid,即使沒有子程序退出,它也會立即返回,不會像wait那樣永遠等下去。而wuntraced引數,由於涉及到一些跟蹤除錯方面的知識,加之極少用到,這裡就不多費筆墨了,有興趣的讀者可以自行查閱相關材料。 看到這裡,聰明的讀者可能已經看出端倪了–wait不就是經過包裝的waitpid嗎?  

說明:程序一旦呼叫了wait,就立即阻塞自己,由wait自動分析是否當前程序的某個子程序已經退出,如果讓它找到了這樣乙個已經變成殭屍的子程序,wait就會收集這個子程序的資訊,並把它徹底銷毀後返回;如果沒有找到這樣乙個子程序,wait就會一直阻塞在這裡,直到有乙個出現為止。

從本質上講,系統呼叫waitpid和wait的作用是完全相同的,但waitpid多出了兩個可由使用者控制的引數pid和options,從而為我們程式設計提供了另一種更靈活的方式。

兩個函式都返回兩個值:函式的返回值和終止的子程序id,而子程序終止的狀態則是通過status指標返回的。

wait&waitpid 的區別是顯而易見的,wait等待第乙個終止的子程序,而waitpid則可以指定等待特定的子程序。

這的區別可能會在下面這種情況時表現得更加明顯:

當同時有5個客戶連上伺服器,也就是說有五個子程序分別對應了5個客戶,此時,五個客戶幾乎在同時請求終止,這樣一來,幾乎同時,五個fin發向伺服器,同樣的,五個sigchld訊號到達伺服器,然而,unix的訊號往往是不會排隊的,顯然這樣一來,訊號處理函式將只會執行一次,殘留剩餘四個子程序作為殭屍程序駐留在核心空間。此時,正確的解決辦法是利用waitpid(-1, &stat, wnohang)防止留下殭屍程序。

其中的pid為-1表明等待任乙個子程序,而wnohang選擇項通知核心在沒有已終止程序項時不要阻塞。

wait&waitpid 區別 :

waitpid提供了wait函式不能實現的3個功能:

1.waitpid等待特定的子程序, 而wait則返回任一終止狀態的子程序;

2.waitpid提供了乙個wait的非阻塞版本;

3.waitpid支援作業控制(以wuntraced選項). 用於檢查wait和waitpid兩個函式返回終止狀態的巨集: 這兩個函式返回的子程序狀態都儲存在status指標中, 用以下3個巨集可以檢查該狀態:

wifexited(status): 若為正常終止, 則為真. 此時可執行 wexitstatus(status): 取子程序傳送給exit或_exit引數的低8位.

wifsignaled(status): 若為異常終止, 則為真.此時可執行 wtermsig(status): 取使子程序終止的訊號編號.

wifstopped(status): 若為當前暫停子程序, 則為真. 此時可執行 wstopsig(status): 取使子程序暫停的訊號編號

注:(網上看到的感覺方法很好,推薦)

如果用在父程序用wait()和waitpid()會使父程序掛起,解決的辦法:

(1).可以用signal函式為sigchld安裝handler。在子程序結束後,父程序會收到該訊號,可以在handler中呼叫wait**。

(2).如果父程序不關心子程序什麼時候結束,那麼可以用signal(sigcld, sig_ign)或signal(sigchld, sig_ign)通知核心,自己對子程序的結束不感興趣,那麼子程序結束後,核心會**,並不再給父程序傳送訊號。

(3).fork兩次,父程序fork乙個子程序,然後繼續工作,子程序fork乙個孫程序後退出,那麼孫程序被init接管,孫程序結束後,init會**。不過子程序的**還要自己做

execl:執行命令;

函式功能:

執行可執行命令;

函式原型:

int execl(const char *path, const char *arg, …);

函式標頭檔案:

《unistd.h》

函式返回值:

成功:則不返回值;失敗:返回-1, 失敗原因存於errno中;

函式引數:

函式說明:execl()用來執行引數path字串所代表的檔案路徑, 接下來的引數代表執行該檔案時傳遞的argv[0],argv[1]…..最後乙個引數必須用空指標null作結束。

例子:

int main( int argc , char **argv )

else

if( 0

wait(null) ;//等待子程式執行結束

printf( "pid is %d \n" , pid ) ;

exit(0) ;

}return

0 ;}

多程序程式設計

linux下乙個程序在記憶體裡有三部份的資料,就是 資料段 堆疊段 和 段 其實學過組合語言的人一定知道,一般的cpu象i386,都有上述三種段暫存器,以方便作業系統的執行。段 顧名思義,就是存放了程式 的資料,假如機器中有數個程序執行相同的乙個程式,那麼它們就可以使用同一 個 段。堆疊段存放的就是...

多程序程式設計

一。多程序程式設計 1.函式學習 1 建立程序 1.函式名 fork 函式原型 pid t fork void 函式功能 建立乙個子程序 所屬標頭檔案 返回值 成功時 在父程序中返回子程序的pid 在子程序中返回是0 失敗時 子程序返回的 1 引數說明 無引數 2.函式名 vfork 函式原型 pi...

多程序程式設計

1.程序是正在執行的程式的例項 每個程序都至少包含乙個執行緒 2.電腦程式是由指令組成的 程序是這些指令的實際執行體 3.程序的狀態 被建立 就緒 執行 阻塞 掛起 終止等狀態 用subprocess模組來管理程序 import subprocess 1.呼叫subprocess.call 建立程序...