研究linux函式 之 fork()

著急的羊發表於2021-01-03


前言

fork,在英語用譯為叉子,形狀像Y,這實在很形象。本來執行的一個app,呼叫fork()函式後就產生了子程式,而原來的程式稱為父程式。


一、儲備知識:程式

  1. 程式可以看做程式的一次執行過程,在linux下每個程式有唯一的PID來標識程式。

特殊程式:

ID為0的是排程程式,該程式是核心的一部分,不執行任何磁碟上的程式
ID為1的是Init程式,init通常讀取與系統有關的初始化檔案(/etc/rc*檔案、/etc/inittab檔案、/etc/init.d/中的檔案)
ID為2的是頁守護程式,負責支援虛擬儲存器系統的分頁操作

  1. linux用程式表來儲存正在執行的程式
    命令ps aux可以檢視所有正在執行的程式
    ps -ef | grep 搜尋內容可以查詢想要的程式
  2. 程式在linux中呈樹狀結構,init為根節點,其它程式均有父程式,某程式的父程式就是啟動這個程式的程式,這個程式叫做父程式的子程式。
  3. fork的作用是複製一個與當前程式一樣的程式。新程式的所有資料(變數、環境變數、程式計數器等)數值都和原程式一致,但是是一個全新的程式,並作為原程式的子程式。

二、fork函式

#include <unistd.h>
pid_t fork(void);
//子程式返回0
//父程式返回子程式ID
//出錯返回-1

fork函式被呼叫一次將返回兩次,在子程式中返回0,在父程式中返回子程式的ID。
子程式獲得父程式的資料空間、堆、棧副本

三、程式建立和死亡

init是永遠不會死亡的。看下面的linux父子程式終止的先後順序不同產生不同的結果:

1)父程式先於子程式終止:

此種情況就是孤兒程式。當父程式先退出時,系統會讓init程式接管子程式 。這也是讓程式進行後臺執行的一種方式,系統apidaemon其實也是呼叫了這一過程

2)子程式先於父程式終止,而父程式又沒有呼叫wait或waitpid函式

此種情況子程式進入殭屍狀態,且會一直保持下去直到系統重啟。子程式處於殭屍狀態時,核心只儲存程式的一些必要資訊以備父程式所需。此時子程式始終佔有著資源,同時也減少了系統可以建立的最大程式數。

殭屍程式:一個已經終止、但是其父程式尚未對其進行善後處理(獲取終止子程式的有關資訊,釋放它仍佔有的資源)的程式被稱為殭屍程式(zombie)。ps命令將殭屍程式的狀態列印為Z 。

3)子程式先於父程式終止,而父程式呼叫了wait或waitpid函式

此時父程式會等待子程式結束。


總結

通過對程式和fork函式做了介紹,兩個概念都要好好理解才能明白他們的互相作用,弄清楚函式背後的原理。後續有新的體會我會再補充,歡迎討論:)

相關文章