#Linux#進程間通信# fork

復刻(英語:fork,又譯作派生分支)是UNIX或類UNIX中的分叉函數,fork函數將運行着的程序分成2個(幾乎)完全一樣的進程,每個進程都啓動一個從代碼的同一位置開始執行的線程。這兩個進程中的線程繼續執行,就像是兩個用戶同時啓動了該應用程序的兩個副本。

fork系統調用用於創建一個新進程,稱爲子進程,它與進程(稱爲系統調用fork的進程)同時運行,此進程稱爲父進程。創建新的子進程後,兩個進程將執行fork()系統調用之後的下一條指令。子進程使用相同的pc(程序計數器),相同的CPU寄存器,在父進程中使用的相同打開文件。

它不需要參數並返回一個整數值。下面是fork()返回的不同值。

  • 負值:創建子進程失敗。
  • :返回到新創建的子進程。
  • 正值:返回父母或來電者。該值包含新創建的子進程的進程ID。

一個進程,包括代碼、數據和分配給進程的資源。fork()函數通過系統調用創建一個與原來進程幾乎完全相同的進程,也就是兩個進程可以做完全相同的事,但如果初始參數或者傳入的變量不同,兩個進程也可以做不同的事。

  一個進程調用fork()函數後,系統先給新的進程分配資源,例如存儲數據和代碼的空間。然後把原來的進程的所有值都複製到新的新進程中,只有少數值與原來的進程的值不同。相當於克隆了一個自己。

我們可以通過一個經典案例來熟悉fork機制。 以下代碼使用gcc編譯

#include "stdio.h"
#include "sys/types.h"
#include "unistd.h"

int main()
{
    pid_t pid1;
    pid_t pid2;

    pid1 = fork();
    pid2 = fork();

    printf("pid1:%d, pid2:%d", pid1, pid2);
}

例如:gcc -o fork_test fork_test.c生成fork_test後運行。

假設父進程輸出的結果是pid1:9268, pid2:9269。那麼執行過程中將一共運行幾個進程,其他幾個進程的輸出結果又是如何

根據fork原理(fork函數將運行着的程序分成2個(幾乎)完全一樣的進程,每個進程都啓動一個從代碼的同一位置開始執行的線程。這兩個進程中的線程繼續執行,就像是兩個用戶同時啓動了該應用程序的兩個副本)fork會上程序切分成二部分A.B二個副本,擁有完全一致的資源。

1)當進程A運行到pid1 = fork();時,創建出副本B,此時A進程得到pid1=9268,B進程同步A進程相關資源。pid1=0, pid2=0

  • A:pid1=9268, pid2=0
  • B:pid1=0, pid2=0

2)當進程A運行到pid2 = fork();時,創建出副本C,此時A進程得到pid2=9269,C進程同步A進程相關資源。pid1=9268, pid2=0

  • A:pid1=9268, pid2=9269
  • B:pid1=0, pid2=0
  • C:pid1=9268, pid2=0

3)當B進程運行到pid2 = fork();時,創建出副本B1,此時B進程得到pid2=9270,B1進程同步B進程相關資源。pid1=0, pid2=0

  • A:pid1=9268, pid2=9269
  • B:pid1=0, pid2=9270
  • C:pid1=9268, pid2=0
  • B1:pid1=9268, pid2=0

程序運行結果如下:

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章