所需頭文件:
#include #include
pid_t vfork(void);
功能:
vfork() 函數(shù)和 fork() 函數(shù)(fork()如何使用,請點(diǎn)此鏈接)一樣都是在已有的進(jìn)程中創(chuàng)建一個(gè)新的進(jìn)程,但它們創(chuàng)建的子進(jìn)程是有區(qū)別的。
參數(shù):
無
返回值:
成功:子進(jìn)程中返回 0,父進(jìn)程中返回子進(jìn)程 ID。pid_t,為無符號整型。
失?。悍祷?-1。
fork() 與 vfock() 都是創(chuàng)建一個(gè)進(jìn)程,那它們有什么區(qū)別呢?
1)fork(): 父子進(jìn)程的執(zhí)行次序不確定。
vfork():保證子進(jìn)程先運(yùn)行,在它調(diào)用 exec(進(jìn)程替換) 或 exit(退出進(jìn)程)之后父進(jìn)程才可能被調(diào)度運(yùn)行。
2)fork(): 子進(jìn)程拷貝父進(jìn)程的地址空間,子進(jìn)程是父進(jìn)程的一個(gè)復(fù)制品。
vfork():子進(jìn)程共享父進(jìn)程的地址空間(準(zhǔn)確來說,在調(diào)用 exec(進(jìn)程替換) 或 exit(退出進(jìn)程) 之前與父進(jìn)程數(shù)據(jù)是共享的)
下面我們寫一個(gè)例子來測試,通過 vfork() 創(chuàng)建的子進(jìn)程會(huì)執(zhí)行完后,才到父進(jìn)程執(zhí)行:
#include #include #include int main(int argc, char *argv[]){ pid_t pid; pid = vfork(); // 創(chuàng)建進(jìn)程 if(pid < 0){="" 出錯(cuò)="" perror('vfork');="" }="" if(0="=" pid){="" 子進(jìn)程="" sleep(3);="" 延時(shí)="" 3="" 秒="" printf('i="" am="" son\n');="" _exit(0);="" 退出子進(jìn)程,必須="" }else="" if(pid=""> 0){ // 父進(jìn)程 printf('i am father\n'); } return 0;}
上面的代碼,已經(jīng)讓子進(jìn)程延時(shí) 3 s,結(jié)果還是子進(jìn)程運(yùn)行結(jié)束后,父進(jìn)程才執(zhí)行,運(yùn)行結(jié)果如下:
接下來,我們一起驗(yàn)證,子進(jìn)程共享父進(jìn)程的地址空間:
#include #include #include int a = 10; int main(int argc, char *argv[]){ pid_t pid; int b = 20; pid = vfork(); // 創(chuàng)建進(jìn)程 if(pid < 0){="" 出錯(cuò)="" perror('vfork');="" }="" if(0="=" pid){="" 子進(jìn)程="" a="100," b="200;" printf('son:="" a="%d," b="%d\n'," a,="" b);="" _exit(0);="" 退出子進(jìn)程,必須="" }else="" if(pid=""> 0){ // 父進(jìn)程 printf('father: a = %d, b = %d\n', a, b); } return 0;}
通常運(yùn)行結(jié)果得知,子進(jìn)程修改 a, b 的值,會(huì)影響到父進(jìn)程的 a, b, 效果圖如下:
vfork() 保證子進(jìn)程先運(yùn)行,在它調(diào)用 exec(進(jìn)程替換) 或 exit(退出進(jìn)程)之后父進(jìn)程才可能被調(diào)度運(yùn)行。如果子進(jìn)程沒有調(diào)用 exec, exit, 程序則會(huì)導(dǎo)致死鎖,程序是有問題的程序,沒有意義,測試代碼如下:
#include #include #include int main(int argc, char *argv[]){ pid_t pid; pid = vfork(); // 創(chuàng)建進(jìn)程 if(pid < 0){="" 出錯(cuò)="" perror('vfork');="" }="" if(0="=" pid){="" 子進(jìn)程="" printf('i="" am="" son\n');="" sleep(1);="" 子進(jìn)程沒有調(diào)用="" exec="" 或="" exit="" }else="" if(pid=""> 0){ // 父進(jìn)程 printf('i am father\n'); sleep(1); } return 0;}
運(yùn)行結(jié)果如下:
所以,用 vfork() 創(chuàng)建進(jìn)程,子進(jìn)程里一定要調(diào)用 exec(進(jìn)程替換) 或 exit(退出進(jìn)程),否則,程序會(huì)出問題,沒有意義。