深度剖析fork()的原理及用法


  我們都知道通過fork()系統調用我們可以創建一個和當前進程印象一樣的新進程.我們通常將新進程稱為子進程,而當前進程稱為父進程.而子進程繼承了父進程的整個地址空間,其中包括了進程上下文,堆棧地址,內存信息進程控制塊(PCB)等.

  1.父子進程

  那么我們首先來先說說父進程和子進程之間的區別:

  • 父進程設置了鎖,子進程不繼承
  • 進程ID不同
  • 子進程的未決告警被清除
  • 子進程的未決信號集設置為空集

  2.fork系統調用說明

  通過man手冊我們可以輕松知道fork()包含的頭文件<sys/types.h>和<unistd.h>,功能就是創建一個子進程.函數原型:pid_t fork(void),pid_t是帶一個代表經常號pid的數據結構.如果創建成功一個子進程,對於父進程來說是返回子進程的ID.而對於子進程來說就是返回0.而返回-1代表創建子進程失敗.

  

  

#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <signal.h>
#include <errno.h>
#include <signal.h>

int main(void)
{
    pid_t pid ;
    signal(SIGCHLD,SIG_IGN);
    printf("before fork pid:%d\n",getpid());
    int abc = 10;      
    pid = fork();          if(pid == -1)   //錯誤返回
    {
        perror("tile");
        return -1;
    }
    if(pid > 0)     //父進程空間
    {
        abc++;
        printf("parent:pid:%d \n",getpid());
        printf("abc:%d \n",abc);
        sleep(20);
    }
    else if(pid == 0){   //子進程空間
        abc++;
        printf("child:%d,parent: %d\n",getpid(),getppid());
        printf("abc:%d",abc);
    }
    printf("fork after...\n");
}before fork pid:27319parent:pid:27319 

before fork pid:27319parent:pid:27319
abc:11
before fork pid:27319child:27320,parent: 27319
abc:11fork after...

 

  3.fork()系統調用注意點:

  通過以上程序我們可以知道:1)fork系統調用之后,父進程和子進程交替執行,並且它們處於不同空間中。

2)fork()函數的一次調用返回2次返回,這個有點抽象難理解,此時二個進程處於獨立的空間,它們各自執行者自己的東西,不產生沖突,所以返回2次一次pid ==0,一次pid大於0.而至於是先子進程還是父進程先執行,這沒有確切的規定,是隨機的.

3)將fork()返回值大於零設置為父進程,這是因為子進程獲得父進程的pid相對容易,而父進程獲子進程pid叫難,所以在在fork()系統調用中將子進程的pid字節有它自己返回給父進程.

4)forl()的子執行過程在fork()之后並不是從頭開始,因為在fork()之前,父進程已經為子進程搭建好了運行環境了.所以字節有效代碼處開始.理解了上面四點,相信我們應該對此系統調用一定有較深的了解.

  4.vfork()系統調用:

  那么講完了fork(),我們不妨和vfork()比較,並且學習終結一下vfork(.);vfork()在某些情況下,我們知道vfork()與fork()執行結果是一樣的,除了子進程會執行一次exec系統調用或者調用_exit(0)退出.函數原型:pid_t vfork vfork(void),具體返回值與其中fork()類似. 這個函數時是在沒有實現寫時賦值前提下,所以現在我們並不推薦使用vfork().

  • 結論如下  1)vfork() 子進程與父進程共享數據段

 2)vfork() 中是子進程先執行,父進程后執行.

  通常我們都是與exec函數在一起,在主進程中替換進程印象.


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM