91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

如何分析Linux內核源碼do_fork

發布時間:2021-11-01 16:20:15 來源:億速云 閱讀:170 作者:柒染 欄目:系統運維

本篇文章為大家展示了如何分析Linux內核源碼do_fork,內容簡明扼要并且容易理解,絕對能使你眼前一亮,通過這篇文章的詳細介紹希望你能有所收獲。

我們都知道進程是Linux內核中最為重要的一個抽象概念,那么我們平時在fork一個進程時,該進程究竟是怎么產生的呢?

推送會淺談一下在進程創建過程中扮演著重要角色的do_fork函數。

內核如何來抽象一個進程

內核通過一個叫做task_struct的結構體來抽象一個進程,該結構體的定義(以內核2.6為例)在include/linux.sched.h中。

截取部分task_struct如下:

如何分析Linux內核源碼do_fork

上述task_struct屬性是我節選出的部分其結構體中的屬性,我們從中可以大致了解到標識一個進程的屬性大致會有該用以表示該進程所處的狀態,進程的標志,以及進程是否被其他進程跟蹤,進程鎖的深度,進程的優先級,進程的pid,進程的父母,進程的孩子鏈表,進程所打開的文件描述符表,進程所處的文件系統,進程的信號。。。。等等一堆我們平時可能遇到的和進程相關的東西。

do_fork簡單分析 

接觸linuxC編程的人都知道,創建一個進程我們需要調用fork函數,fork其實又是調用了clone函數來實現的,而clone函數中最關鍵的函數就是do_fork函數。

在分析do_fork前我們腦海中可以大致想象一下,進程究竟是如何被創建出來的,假如讓你來創建一個進程你會咋么做?

我們可以這樣去分析,既然原來的進程被抽象成一個task_struct,那么新進程也是一個task_struct只不過它里面的一些屬性會不同與原來的task_struct,那么創建一個新進程所要做的工作就是賦值一個與原來進程一樣都的task_struct結構,然后然后將新進程的task_struct不同于原來task_struct的屬性進行修改即可。

do_fork定義在kernel/fork.c文件中。

在分析該函數之前我們先來分析一下它的函數的各個參數。

參數如下: 

如何分析Linux內核源碼do_fork

1.clone_flags:該參數是此函數中最重要的一個參數,該值中的每個位都代表對子進程task_struct中的每種屬性的設置;

2.stack_start:子進程用戶態堆棧的開始地址;

3.regs:當系統發生系統調用時,需從用戶態切換到內核態,此結構體用來保存此時用戶態進程中的通用寄存器中的值,并被存放在內核態堆棧中;

4.stack_size:目前未被使用,通常設為0;

5.parent_tidptr:父進程在用戶態下pid的地址;

6.child_tidptr:子進程在用戶態下pid的地址;

其中clone_flags的標志位宏定義如下: 

如何分析Linux內核源碼do_fork

舉個簡單的例子當我們的參數中設置了CLONE_VM這個宏,那么就以為這我們新創建的進程和其父進程要共享VM,當我們設置了CLONE_FILES時意味這父子進程之間共享打開的文件描述符。

do_fork開始執行后首先做的就是為子進程定義一個新的task_struct指針:

struct task_struct *p;

在下來會檢查一些clone_flags所不允許的位組合,例如:

if (clone_flags & CLONE_NEWUSER) {  if (clone_flags & CLONE_THREAD)  return -EINVAL;  }

上述中不允許同時既設置了CLONE_NEWUSER標志,還設置CLONE_THREAD標志,這樣就會產生錯誤。

類似上面當一系列的安全檢查完畢之后,copy_process函數就登場了,copy_process函數工作流程具體如下:

1)調用dup_task_struct函數為新的進程創建一個內核棧,thread_info結構和task_struct等,當然此時的值都是和父進程完全一樣的

dup_task_struct函數定義如下:

如何分析Linux內核源碼do_fork

如何分析Linux內核源碼do_fork

2)檢查并確保新創建該子進程后,當前用戶所擁有的進程數沒有超出給它分配的資源限制,代碼如下: 

如何分析Linux內核源碼do_fork

3)子進程著手使自己與父進程區別開來,從父進程那繼承過來的許多屬性都要被清0或設置一個初始值,但task_struct中的大多數數據還是未被修改,部分代碼如下:

如何分析Linux內核源碼do_fork

如何分析Linux內核源碼do_fork 

4)給子進程分配一個CPU,代碼如下:

sched_fork(p, clone_flags);

5) 接著就是子進程拷貝父進程的一些資源,具體如下,調用copy_files函數拷貝父進程打開的文件描述符:  

如何分析Linux內核源碼do_fork

調用copy_fs繼承父進程所屬的文件系統。 

如何分析Linux內核源碼do_fork

調用copy_signal函數拷貝并設置新的signal_struct,signal_struct包含了大量的進程運行的信息,調用copy_mm函數處理與新進程的內存問題。 

如何分析Linux內核源碼do_fork

調用copy_io函數拷貝父進程的I/O情況:

如何分析Linux內核源碼do_fork 

還有調用copy_namespaces 和 copy_thread等,這里就不在贅述。

6)調用alloc_pid為新進程分配一個pid。

pid = alloc_pid(p->nsproxy->pid_ns);

7)copy_process做一些收尾工作,并返回新進程的task_struct指針,此時再次回到了do_fork,新創建的子進程被喚醒,并讓其先投入運行。

如何分析Linux內核源碼do_fork 

總結

關于進程創建的源碼理解,我感覺主要抓住倆點即可。***進程被內核抽象成了啥?它的數據結構是咋樣的(task_struct)這點我們必須有所認識,第二創建進程最主要的其實就是拷貝父進程的task_struct里的屬性,但是關鍵點是拷貝哪些,哪些又是子進程和父進程所不同的,很簡單我們只需要把握住進程創建函數里的clone_flags參數就可以知道怎么拷貝了。

上述內容就是如何分析Linux內核源碼do_fork,你們學到知識或技能了嗎?如果還想學到更多技能或者豐富自己的知識儲備,歡迎關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

卢龙县| 濉溪县| 乳山市| 朔州市| 金坛市| 睢宁县| 定兴县| 宁河县| 秦安县| 城口县| 北碚区| 嵊泗县| 财经| 毕节市| 高淳县| 海原县| 大石桥市| 松桃| 宜春市| 湘西| 大厂| 安达市| 铅山县| 海南省| 富民县| 榆社县| 萝北县| 广饶县| 南昌市| 余干县| 六安市| 锦州市| 桑日县| 山东省| 伊春市| 个旧市| 齐河县| 留坝县| 长葛市| 藁城市| 固始县|