1. 程式人生 > >Linux 多工程式設計——多程序:vfork() 函式詳解

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 
版權宣告:本文為博主原創文章,轉載請附上博文連結!