fork原始碼剖析

2021-09-07 15:53:42 字數 2762 閱讀 8522

1.什麼是程序?

程序可以理解為正在執行的程式。程序控制塊(pcb)有作業系統建立和管理。程序控制塊是作業系統能夠支援多程序和提供多處理的關鍵工具。

2.程序的建立:1)分配pcb 2)分配位址空間

1.fork()建立新程序

#include#includepid_t fork(void);
fork()函式的每次呼叫都返回兩次,在父程序中返回的時子程序的pid,在子程序中則返回為0。該返回值用於判斷是父程序還是子程序。fork呼叫失敗時返回-1,並設定errno。

2.父程序呼叫fork()函式建立子程序過程中,子程序的pcb拷貝父程序的pcb,父程序的資料也會複製到子程序中。資料的複製採用寫時複製,即在任一程序對資料執行寫操作時,先產生缺頁中斷,然後作業系統給子程序分配記憶體並複製父程序的資料。建立子程序後,父程序中開啟的檔案描述符預設在子程序中也是開啟的,且檔案描述符的引用計數+1。父程序的使用者根目錄、當前工作目錄等變數的引用計數均會+1.

3.fork() vfork() clone()都是系統呼叫,他們的底層都是do_fork() 函式呼叫,只是引數不同

1.轉到do_fork()定義

(1)定義乙個pcb指標struct task_struct *p;

(2)申請乙個pid

pid是乙個整型變數,最大值不會超過整型所表示的最大範圍,在2.6核心中pid自身有限制預設為32768.

(3)複製程序描述符copy_process()

1)子程序獲取程序描述符dup_task_struct()

$1、alloc_task_struct巨集為新程序獲取程序描述符,並將描述符儲存到tsk區域性變數中

$2、alloc_thread_info巨集獲取一塊空閒記憶體區

/* alloc_thread_info巨集獲取一塊空閒記憶體區,用來存放新程序的thread_info結構和核心棧

這塊記憶體區字段的大小是8kb或者4kb。

2)複製檔案描述符copy_files(),記憶體描述符copy_mm()

/ * 複製程序檔案描述符 */

static int copy_files(unsigned long clone_flags, struct task_struct * tsk)

...} /* 當建立乙個新的程序時,核心呼叫copy_mm函式,

這個函式通過建立新程序的所有頁表和記憶體描述符來建立程序的位址空間。

通常,每個程序都有自己的位址空間,但是輕量級程序共享同一位址空間,即允許它們對同一組頁進行定址。

*/ static int copy_mm(unsigned long clone_flags, struct task_struct * tsk)

struct mm _struct * mm 記憶體描述符,描述程序位址的全部資訊

3)拷貝執行緒copy_thread()呼叫copy_thread,用發出clone系統呼叫時cpu暫存器的值(它們儲存在父程序的核心棧中)

copy_thread()用父程序的現場資訊初始化子程序的現場資訊,把eax暫存器對應欄位的值強制置為0,這是子程序返回值為0的原因。

/* 呼叫copy_thread,用發出clone系統呼叫時cpu暫存器的值(它們儲存在父程序的核心棧中)	

來初始化子程序的核心棧。不過,copy_thread把eax暫存器對應欄位的值(這是fork和clone系統呼叫在子程序中的 返回值)

強行置為0。子程序描述符的thread.esp欄位初始化為子程序核心棧的基位址。ret_from_fork的位址存放在thread.eip中。

如果父程序使用io許可權位圖。則子程序獲取該位圖的乙個拷貝。

最後,如果clone_settls標誌被置位,則子程序獲取由clone系統呼叫的引數tls指向的使用者態資料結構所表示的tls段。 */

retval = copy_thread(0, clone_flags, stack_start, stack_size, p, regs);

if (retval)

goto bad_fork_cleanup_namespace;

4)狀態置為就緒,父程序時間片分子程序一半,防止通過程式通過fork惡意占用cpu資源

/* 呼叫sched_fork完成對新程序排程程式資料結構的初始化。	

該函式把新程序的狀態置為task_running,並把thread_info結構的preempt_count欄位設定為1。

從而禁止搶占。

此外,為了保證公平排程,父子程序共享父程序的時間片。

*/ sched_fork(p);

原始碼剖析 Hashtable 原始碼剖析

hashtable同樣是基於雜湊表實現的,同樣每個元素都是key value對,其內部也是通過單鏈表解決衝突問題,容量不足 超過了閾值 時,同樣會自動增長。hashtable也是jdk1.0引入的類,是執行緒安全的,能用於多執行緒環境中。hashtable同樣實現了serializable介面,它支...

fork原始碼總結

在linux系統下,fork 的實現是通過呼叫clone 實現的,這一呼叫通過不同的引數來指明父子程序之間需要共享的資源。其中fork vfork clone庫函式都是通過系統呼叫clone 然後再由clone呼叫do fork 實現。dofork 完成了建立的大部分工作,定義在kernel for...

python原始碼剖析 Python原始碼剖析

第頁共 頁python 原始碼剖析 物件機制 1.物件 在python 的世界中,一切都是物件,乙個整數是乙個物件,乙個字串也是 乙個物件,更為奇妙的是,型別也是乙個物件,整數型別是乙個物件,字串類 型也是乙個物件。從 年guido 在那個聖誕節揭開 python 世界的大幕開始,一直到現在,pyt...