程序控制之vfork函式

2022-05-04 20:18:20 字數 1473 閱讀 3364

vfork函式的呼叫序列和返回值與fork相同,但兩者的語義不同。

vfork用於建立乙個新程序,而新程序的目的是exec乙個新程式。vfork和fork一樣都建立乙個子程序,但是它並不將父程序的位址空間完全複製到子程序中,因為子程序會立即呼叫exec(或exit),於是也就不會存訪該位址空間。相反,在子程序呼叫exec或exit之前,它在父程序的空間中執行。

vfork和fork之間的另乙個區別是:vfork保證子程序先執行,在它呼叫exec或exit之後父程序才可能被排程執行。(如果在呼叫這兩個函式之前子程序依賴於父程序的進一步動作,則會導致死鎖。)

程式清單8-2 vfork函式例項

[root@localhost apue]# cat prog8-2

.c#include

"apue.h

"int glob = 6; /*

external variable in initialized data

*/int

main(

void

)

else

if(pid == 0) /*

child

*/

/** parent continues here.

*/printf(

"pid = %d, glob = %d, var = %d\n

", getpid(), glob, var

); exit(0);

}

執行該程式得到:

[root@localhost apue]# ./prog8-2

before vfork

pid = 15792, glob = 7, var = 89

子程序最變數glob和var做增1操作,結果改變了父程序中的變數值。因為子程序在父程序的位址空間中執行。

注意,在程式清單8-2中,呼叫了_exit而不是exit。_exit並不執行標準i/o緩衝的沖洗操作。如果呼叫的是exit而不是_exit,則該程式的輸出是不確定的。它依賴於標準i/o庫的實現,我們可能會見到輸出沒有發生變化,或者發現沒有出現父程序的printf輸出。

如果子程序呼叫exit,而exit的實現只是沖洗所有標準i/o流,那麼我們會見到輸出與子程序呼叫_exit所產生的輸出完全相同,沒有任何區別。如果exit的實現除了沖洗所有標準i/o流之外,還關閉標準i/o流,那麼表示標準輸出file物件的相關儲存區將被清0。因為子程序借用了父程序的位址空間,所以當父程序恢復執行並呼叫printf時,也就不會產生任何輸出,printf返回-1。注意,父程序的stdout_fileno仍舊有效,子程序得到的是父程序的檔案描述符陣列的副本。

本篇博文內容摘自《unix環境高階程式設計》(第二版),僅作個人學習記錄所用。關於本書可參考:

Unix程序控制之1 fork和vfork函式

一 fork函式 乙個執行中的程序可以呼叫fork 函式來產生乙個新的程序,函式原型及標頭檔案定義如下 include pid t fork void returns 0 in child,process id of child in parent,1 on error 下面有幾個細節性問題來說明 ...

程序控制之exec函式

1.exec函式 include int execl const char pathname,const char arg0,char 0 int execv const char pathname,const char argv int execle const char pathname,con...

程序控制之system函式

1.system函式 include int system const char cmd 如果cmd是乙個空指標,則僅僅當命令處理程式可用時,system返回非0值。因為system在其實現中呼叫了fork,exec和waitpid,因此有三種返回值 1 如果fork失敗或者waitpid返回除ei...