成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Linux是如何創建進程的?為什么說Linux與其他操作系統不同?

系統 Linux 新聞
前面兩節簡要地從C語言源代碼層面討論了Linux系統中進程的基本概念,我們知道了Linux內核如何描述和記錄進程的資源,以及進程的五種基本狀態和進程的家族樹。事實上,就進程管理而言,Linux還是有一些獨特之處的。

前面兩節簡要地從C語言源代碼層面討論了Linux系統中進程的基本概念,我們知道了Linux內核如何描述和記錄進程的資源,以及進程的五種基本狀態和進程的家族樹。事實上,就進程管理而言,Linux還是有一些獨特之處的。

[[272837]]

Linux 系統中的進程創建

許多操作系統都提供了專門的進程產生機制,比較典型的過程是:首先在內存新的地址空間里創建進程,然后讀取可執行程序,裝載到內存中執行。

Linux 系統創建線程并未使用上述經典過程,而是將創建過程拆分到兩組獨立的函數中執行:fork() 函數和 exec() 函數族。

基本流程是這樣的:首先,fork() 函數拷貝當前進程創建子進程。產生的子進程與父進程的區別僅在與 PID 與 PPID 以及某些資源和統計量,例如掛起的信號等。準備好進程運行的地址空間后,exec() 函數族負責讀取可執行程序,并將其加載到相應的位置開始執行。

Linux 系統創建進程使用的這兩組函數效果與其他操作系統的經典進程創建方式效果是相似的,可能有讀者會覺得這么做會讓進程創建過于繁瑣,其實不是的,Linux 這么做的其中一個原因是為了提高代碼的復用率,這得益于 Linux 高度概括的抽象,無需再額外設計一套機制用于創建進程。

“寫時拷貝”

早期 Linux 中的 fork() 函數直接把父進程的所有資源賦值給創建出的子進程,這樣的機制自然是簡單的,但是效率卻比較低下。

原因是顯而易見的:子進程并不一定要使用父進程的資源,或者子進程可能僅需以只讀的方式訪問父進程的資源,這時“拷貝一份資源”就純屬多余的開銷了。

針對這樣的問題,Linux 后續版本中的 fork() 函數開始采用“寫時拷貝”機制。寫時拷貝技術可以將拷貝需求延遲,甚至免除拷貝,減小開銷。

具體來說就是,Linux 在調用 fork() 創建子進程時,并不著急拷貝整個進程地址空間,而是暫時讓父子進程以只讀的方式共享同一個拷貝。拷貝動作只在子進程需要寫入時才會發生,以確保各個進程有自己獨立的內存空間。

如果子進程用不到或者只需要讀取共享空間數據,那么拷貝動作就被省去了,Linux 就減小了開銷。例如,系統調用 fork() 后立即調用 exec(),此時 exec() 會加載新的映像覆蓋 fork() 的地址空間,拷貝動作完全可以省去。

事實上,fork() 函數的實際開銷就是復制父進程的頁表以及給子進程創建唯一的進程描述符。在大多數情況下,Linux 創建進程后都會馬上運行新的可執行程序,因此“寫時拷貝”機制可以避免相當多的數據拷貝。創建進程速度快是 Linux 系統的一個特征,因此“寫時拷貝”是一種相當重要的優化。

創建進程時,內存地址空間里常常包含數十 MB 的數據,如果每創建一次進程,就拷貝一次數據,開銷顯然是非常大的。

fork() 函數

Linux 中的 fork() 函數其實是基于 clone() 實現的,clone() 函數可以通過一系列參數標志指定父子進程需要共享的資源,在 Linux 中輸入 man 命令可以查看 clone() 函數的C語言原型:

Linux是如何創建進程的?為什么說Linux與其他操作系統不同?

clone() 函數的C語言原型

以及相關的參數標志:

Linux是如何創建進程的?為什么說Linux與其他操作系統不同?

相關的參數標志

在Linux中,fork() 函數最終調用了 do_fork() 函數,它的C語言代碼如下,請看(do_fork() 函數的C語言代碼比較長,下面面只列出了一部分):

Linux是如何創建進程的?為什么說Linux與其他操作系統不同?

do_fork() 函數的C語言代碼

do_fork() 函數完成了進程創建的大部分工作,從相關的C語言源代碼可以看出,它調用了 copy_process() 函數,copy_process() 函數的C語言源代碼如下,請看:

Linux是如何創建進程的?為什么說Linux與其他操作系統不同?

copy_process() 函數的C語言源代碼

copy_process() 函數的代碼也是比較長的,在我手上的Linux系統中,達到了近 400 行,不過代碼的整體邏輯是清晰的:

(1)copy_process() 函數首先檢查了一些標志位,接著調用 dup_task_struct() 函數為新進程創建內核棧,以及上一節提到的 thread_info 和 task_struct 結構:

Linux是如何創建進程的?為什么說Linux與其他操作系統不同?

調用 dup_task_struct() 函數為新進程創建內核棧

創建后,接下來的 arch_dup_task_struct() 函數會將 orig 結構拷貝給新創建的結構,查看相關C語言代碼,這一過程是清晰的:

Linux是如何創建進程的?為什么說Linux與其他操作系統不同?

拷貝給新創建的結構

此時子進程和父進程的描述符是完全相同的。

(2)接下來,需要檢查一些標志位和統計信息,相關的C語言代碼如下,請看:

Linux是如何創建進程的?為什么說Linux與其他操作系統不同?

檢查一些標志位和統計信息

(3)將一些統計量清零,以及初始化一些區別成員,此時雖然新進程的 task_struct 結構體大多成員未被修改,但是父子進程已經有所區別。這一過程的相關C語言代碼片段如下,請看:

Linux是如何創建進程的?為什么說Linux與其他操作系統不同?

將一些統計量清零,以及初始化一些區別成員

(4)將新創建的子進程狀態設置為 TASK_UNINTERRUUPTIBLE,確保其暫時不會被投入運行,這一過程的C語言代碼相對簡單。

(5)調用 alloc_pid() 函數為新進程分配一個獨一無二的 pid,相關C語言代碼如下,請看:

Linux是如何創建進程的?為什么說Linux與其他操作系統不同?

為新進程分配一個獨一無二的 pid

(6)根據 clone() 函數的參數標志位,拷貝或共享已經打開的文件、文件系統、信號處理函數、進程地址空間等資源,例如下面這段C語言代碼:

Linux是如何創建進程的?為什么說Linux與其他操作系統不同?

拷貝或共享已經打開的資源

(7)將為新進程創建的 task_struct 結構體的指針返回給調用者,也即 do_fork() 函數。此時新創建的進程還沒有被投入運行。

現在回到 do_fork() 函數。如果調用 clone() 函數時,沒有傳遞 CLONE_STOPPED 參數,新創建的進程將被喚醒,并投入運行,這一過程的C語言代碼如下:

Linux是如何創建進程的?為什么說Linux與其他操作系統不同?

喚醒,并投入運行

到這里,一個新的進程就被 Linux 創建完畢了。

Linux 內核有意讓新創建的子進程先運行,因為子進程常常會立即調用 exec() 函數加載新的程序到內存中運行,這樣就避免了寫時拷貝的額外開銷。如果父進程首先執行,顯然極有可能開始往地址空間寫入操作,導致拷貝動作發生。

小結

本節詳細的從C語言代碼層面分析了Linux內核創建進程的過程,可見,即使是復雜的操作系統代碼,也是通過一系列基本C語言語法和函數實現的。那么,Linux 是如何創建線程的呢?之前我們曾經提到,Linux 系統并不特別區分進程和線程,線程其實是一種特殊的進程,Linux 是如何實現這一“特殊”過程的呢?限于篇幅,下一節再說了,敬請關注。

責任編輯:華軒 來源: 今日頭條
相關推薦

2010-03-25 14:45:24

Linux桌面環境

2016-01-08 13:54:31

DebianLinux發行版

2025-05-12 09:12:59

2009-12-14 18:27:21

Linux操作系統

2010-01-05 17:16:51

2010-01-06 15:41:07

Linux操作系統

2021-09-01 09:50:02

K8S容器

2024-02-26 08:49:32

NewbingAI模型

2009-12-14 17:36:18

2013-09-16 15:15:44

Linux操作系統

2019-04-28 10:30:30

Linux操作系統Namespace

2009-12-15 18:27:51

Linux操作系統

2023-04-13 08:09:35

操作系統虛擬地址內存

2022-09-29 09:17:47

進程Linux創建

2012-09-21 14:35:01

2019-09-23 13:10:02

容器進程

2009-08-28 10:43:38

2014-10-30 13:36:55

開源系統

2022-07-29 10:42:51

Linux隱私

2020-12-17 18:30:44

華為鴻蒙智能手機操作系統
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 在线视频h | 精品成人免费一区二区在线播放 | 成人在线免费视频 | 亚洲国产高清高潮精品美女 | 在线看片福利 | 国产精品一区在线观看 | 国产一级片久久久 | 一级a爱片久久毛片 | 欧美在线视频免费 | 黄色在线网站 | 国产精品视频偷伦精品视频 | 国产精品一区二区三 | 一区免费观看 | 久在线| 精品久久99 | 在线看无码的免费网站 | 91久久北条麻妃一区二区三区 | 日韩在线高清 | 成人精品视频 | 亚洲 欧美 另类 综合 偷拍 | 日韩欧美国产一区二区三区 | 久久国内精品 | 羞羞视频网页 | 亚洲欧洲激情 | 国产精品一区二区三区在线 | 欧美精品一区在线 | 天天爽夜夜骑 | 国产精品123区 | 亚洲 中文 欧美 日韩 在线观看 | 久久精品国产免费看久久精品 | 国产精品久久久久久吹潮日韩动画 | 欧美综合在线观看 | 欧美一区二区三区在线视频 | 九九亚洲 | 一本一道久久a久久精品蜜桃 | 久久国产精品免费一区二区三区 | 在线视频一区二区 | 中文字幕一区二区三区四区五区 | 日本成人三级电影 | 中文二区 | 国产黄色免费网站 |