天天看點

建立程序-fork函數

     最近,我在Linux中學到了一個神奇的函數,名為fork()函數,它的作用是建立程序。它的神奇之處在于調用fork()函數時,系統會建立一個與原來程序幾乎完全相同的程序,大緻的意思就是兩個程序可以做完全相同的事,但如果初始參數或者傳入的變量不同,兩個程序也可以做不同的事  。就相當于是克隆了一個自己。

     先來看一個例子

#include <stdio.h>
#include <string.h>
#include <assert.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>

int main()
{
   pid_t res=fork();
   assert(res!=-1);
   
   if(res==0)
   {
       printf("hello\n");
       exit(0);
   }
   else
   {
       printf("world\n");
       exit(0);
   }

}
           

     大家一定都很好奇結果是什麼?那麼結果到底是什麼呢?

     運作結果是 

world

hello

     在語句res=fork()之前,隻有一個程序在執行這段代碼,但是在這條語句之後,就變成兩個程序在執行了,這兩個程序幾乎完全相同,将要執行的下一條語句都是if(res<0),為什麼兩個程序執行的結果會不同呢?這與fork函數的特性有關。

    fork函數的神奇之處就在于它僅僅被調用一次,卻能夠傳回兩次,它有三種不用的傳回值

       1)、在新建立的程序即子程序中傳回0

       2)、在調用fork函數的程序即父程序中傳回新建立程序的ID

       3)、如果出現錯誤,fork函數傳回一個負值

     在fork函數執行完畢後,如果建立程序成功,則出現兩個程序,一個父程序和一個子程序。在子程序中,fork函數傳回0。在父程序中,fork函數傳回子程序的程序号。是以,我們就可以通過fork的傳回值來判斷目前程序是父程序還是子程序。

     父程序和子程序都是從fork函數之後的代碼開始執行,那麼在條件之外的語句又該如何執行呢?

      int main()

      {

           if(res==0)

           {子程序執行}

           else

           {父程序執行}

           父子程序都執行

      }

   下面請看第二個例子 

#include <stdio.h>
#include <string.h>
#include <assert.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>


int main()
{
   pid_t res=fork();
   assert(res!=-1);
   
   if(res==0)
   {
       printf("你好\n");
   }
   else
   {
       printf("中國\n");
   }
   printf("你好,中國");

}
           

   根據上面介紹的父程序與子程序的執行順序,結果是 :

中國          

你好,中國

你好

你好,中國

    之前的例子隻是簡單的練手,現在重點來了,請看第三個例子 

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <assert.h>

int main()
{
    int i=0;
    for(;i<2:++i)
    {
        if(fork())
        {
           printf("A\n");
        }
        else
        {
           printf("B\n");
        }
    }
}
           

  這個例子較之前的兩個更加複雜一點,那麼這個結果是什麼呢?請看下圖解析過程

建立程式-fork函數

    如上圖所示,結果為三個A三個B(與順序無關)。當i=0時,第一個程序建立一個新程序,即黑色箭頭産生,結果為黑色字母。當i=1時,第一次建立的兩個程序分别建立一個程序,為圖中紅色箭頭,結果為紅色結果。至于兩個程序誰先建立程序,暫不研究。

      本次fork函數講解就完了,希望大家能多多提出意見。 

建立程式-fork函數

    

繼續閱讀