Linux 多工程式設計——多程序:vfork() 函式詳解
所需標頭檔案:
#include <sys/types.h>
#include <unistd.h>
pid_t vfork(void);
功能:
vfork() 函式和 fork() 函式(fork()如何使用,請點此連結)一樣都是在已有的程序中建立一個新的程序,但它們建立的子程序是有區別的。
引數:
無
返回值:
成功:子程序中返回 0,父程序中返回子程序 ID。pid_t,為無符號整型。
失敗:返回 -1。
fork() 與 vfock() 都是建立一個程序,那它們有什麼區別呢?
1)fork(): 父子程序的執行次序不確定。
vfork():保證子程序先執行,在它呼叫 exec(程序替換) 或 exit(退出程序)之後父程序才可能被排程執行。
2)fork(): 子程序拷貝父程序的地址空間,子程序是父程序的一個複製品。
vfork():子程序共享父程序的地址空間(準確來說,在呼叫 exec(程序替換) 或 exit(退出程序) 之前與父程序資料是共享的)
下面我們寫一個例子來測試,通過 vfork() 建立的子程序會執行完後,才到父程序執行:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(int argc, char *argv[])
{
pid_t pid;
pid = vfork(); // 建立程序
if(pid < 0){ // 出錯
perror("vfork");
}
if(0 == pid){ // 子程序
sleep(3); // 延時 3 秒
printf("i am son\n");
_exit(0); // 退出子程序,必須
}else if(pid > 0){ // 父程序
printf("i am father\n");
}
return 0;
}
上面的程式碼,已經讓子程序延時 3 s,結果還是子程序執行結束後,父程序才執行,執行結果如下:
接下來,我們一起驗證,子程序共享父程序的地址空間:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int a = 10;
int main(int argc, char *argv[])
{
pid_t pid;
int b = 20;
pid = vfork(); // 建立程序
if(pid < 0){ // 出錯
perror("vfork");
}
if(0 == pid){ // 子程序
a = 100, b = 200;
printf("son: a = %d, b = %d\n", a, b);
_exit(0); // 退出子程序,必須
}else if(pid > 0){ // 父程序
printf("father: a = %d, b = %d\n", a, b);
}
return 0;
}
通常執行結果得知,子程序修改 a, b 的值,會影響到父程序的 a, b, 效果圖如下:
vfork() 保證子程序先執行,在它呼叫 exec(程序替換) 或 exit(退出程序)之後父程序才可能被排程執行。如果子程序沒有呼叫 exec, exit, 程式則會導致死鎖,程式是有問題的程式,沒有意義,測試程式碼如下:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(int argc, char *argv[])
{
pid_t pid;
pid = vfork(); // 建立程序
if(pid < 0){ // 出錯
perror("vfork");
}
if(0 == pid){ // 子程序
printf("i am son\n");
sleep(1);
// 子程序沒有呼叫 exec 或 exit
}else if(pid > 0){ // 父程序
printf("i am father\n");
sleep(1);
}
return 0;
}
執行結果如下:
所以,用 vfork() 建立程序,子程序裡一定要呼叫 exec(程序替換) 或 exit(退出程序),否則,程式會出問題,沒有意義。
---------------------
作者:Mike__Jiang
來源:CSDN
原文:https://blog.csdn.net/tennysonsky/article/details/45847107
版權宣告:本文為博主原創文章,轉載請附上博文連結!