Linux 程序建立筆記

2022-07-26 08:30:19 字數 1734 閱讀 7591

一般的作業系統如果想要 spwan 乙個程序,一般會經過幾個步驟,先在新的位址空間中建立程序,然後讀入可執行檔案,最後開始執行這個可執行檔案。linux 下,這幾個階段分別由兩個函式獨立完成,fork() 負責建立乙個子程序。exec() 則負責讀入可執行檔案並開始執行。

fork() 的作用就進行程序複製。linux 下一共實現了三種類似的功能,分別是 fork(), vfork() 和 clone () 。

fork()

fork() 函式是乙個重量級的程序複製,在邏輯上而言,子程序在最初應該具有和父程序一樣的記憶體頁,建立父程序完整的副本資訊。然而基於 「建立子程序後,大概率會執行同父程序完全不同的應用程式」 這個現象後,通常對子程序都是用 copy on write 技術,即核心此時並不會複製整個程序的位址空間,而是讓父程序和子程序共享同乙個拷貝,子程序擁有了乙個同父程序一樣的頁表 ,這樣,子程序和父程序就擁有了一樣的虛擬位址空間和實際實體地址空間的對應關係。他們指向同樣的物理記憶體頁。不過,由於他們只是短暫的共享了資料,所以他們並不能修改彼此之間的頁。

vfork()

vfork() 同 fork() 類似,但他顯式的沒有建立父程序的副本,子程序和父程序之間可以直接進行資料共享。 vfork() 的設計是為了子程序生成後直接進行 exec() 系統呼叫設計的。顯然這種方式快於 fork() ,但是,由於 cow 的出現,fork() 和 vfork() 在速度上已經沒有明顯的區別。在 vfork() 生成子程序後,父程序被阻塞,直到子程序退出或者執行 exec() 呼叫。由於 fork() 已經實現了 cow 技術,所以現在基本上都在使用 fork()。

clone()

clone()主要用於產生執行緒,可以對父子程序之間進行資料共享,複製。做到精確的控制。

fork() vfork() clone() 他們的實現的具體細節各有不同,但最後負責程序複製的函式都是一樣的,為 do_fork() 函式

do_fork() 函式

do_fork 函式先呼叫 copy_progress() 函式用來生成新的程序,copy_progress() 根據標誌指定需要重用的父程序的資料,生成新的子程序。在子程序生成以後,需要對子程序獲得其 pid。如果是使用 vfork() 函式進行呼叫,那麼父程序會進入睡眠狀態,直到子程序呼叫 exec() 或者退出。通過這樣的方式,保證了父程序和子程序彼此之間對共享的變數互不干擾。然後子程序把其自身的 task_struct 新增到排程器佇列,進行程序排程。對於新fork 的子程序,排程器會讓其有較高的機率先執行。如果子程序在父程序前進行執行,那麼會降低複製記憶體頁帶來的額外開銷。

copy_progress() 用來進行資源的複製,生成子程序的過程。它首先為新的子程序建立乙個自己的核心棧,thread_info和 task_struct 等資訊,這些值同父程序的值相同,在這個時候,父程序和子程序的描述符完全相同。

然後檢查需要分配的資源數量,確保沒有超出資源限制,不會出現資源不足。如果出現了資源不足的現象,那麼會呼叫 sched_fork() 函式,讓排程器重新對新的程序進行設定。

接著,為了區別開子程序和父程序,子程序開始對程序描述符內的資訊進行修改。

設定子程序的狀態為 uninterruptible 型別,確保其現在不會投入執行中。

子程序繼續複製父程序的一些核心資源,對於這些資源,都有相應的標誌位用來表示資源狀態。如果標誌位為1,那麼表示兩個程序共享這些資源,反之,說明子程序擁有了自己的資源資訊

當做完這些工作後,會進行一些掃尾工作,然後返回乙個指向子程序的指標。

以上,就是 linux 程序建立的大概過程和一些細節步驟。

Linux程序執行緒學習筆記 程序建立

linux程序執行緒學習筆記 程序建立 周銀輝各位同學,轉換下思維,這裡說的是 程序 不是 執行緒 ok,我們開始 程序 二字似乎總有那麼些 只可意會不可言傳 的韻味,維基百科是這樣來解釋的 也有朋友如此來闡述,乙個可以執行的程式 和該程序相關聯的全部資料 包括變數,記憶體空間,緩衝區等等 程式的執...

Linux 程序建立

華清遠見嵌入式學院 上海分中心講師。在 linux 核心內,程序是由相當大的乙個稱為 task struct 的結構表示的。此結構包含所有表示此程序所必需的資料,此外,還包含了大量的其他資料用來統計 accounting 和維護與其他程序的關係 父和子 下面給出了 task struct 的一小部分...

Linux 程序建立

1 linux建立程序的方式是先通過呼叫fork建立乙個和呼叫程序基本一樣的子程序,二者之間的區別在於pid和ppid不同。然後子程序呼叫exec函式裝載乙個新的程序到位址空間執行。其他的作業系統產生子程序的方式是spawn 在新的位址空間中建立程序,然後載入可執行檔案執行。2 傳統的fork是將所...