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

Linux內核源碼do_fork分析

系統 Linux 系統運維
我們都知道進程是Linux內核中最為重要的一個抽象概念,那么我們平時在fork一個進程時,該進程究竟是怎么產生的呢? 本篇推送會淺談一下在進程創建過程中扮演著重要角色的do_fork函數。

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

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

內核如何來抽象一個進程

 

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

截取部分task_struct如下: 

截取部分task_struct 

上述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文件中。

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

參數如下:  

參數 

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

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

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

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

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

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

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

clone_flags的標志位宏定義 

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

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

struct task_struct *p;

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

  1. if (clone_flags & CLONE_NEWUSER) {  if (clone_flags & CLONE_THREAD)  return -EINVAL; 
  2.  
  3. }  

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

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

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

dup_task_struct函數定義如下: 

dup_task_struct函數定義

 

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

 

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

 

  

 

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

  1. sched_fork(p, clone_flags); 

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

 

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

 

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

 

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

 

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

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

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

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

 

總結 

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

責任編輯:龐桂玉 來源: 西郵Linux興趣小組
相關推薦

2023-04-28 08:42:08

Linux內核SPI驅動

2009-12-11 09:42:54

Linux內核源碼進程調度

2009-12-11 09:47:23

Linux內核源碼進程調度

2014-07-29 15:44:33

Linux內核Crash

2021-12-15 15:03:51

Linux內核調度

2023-05-08 07:41:07

Linux內核ELF文件

2020-07-28 08:54:39

內核通信Netlink

2017-08-16 16:20:01

Linux內核態搶占用戶態搶占

2021-09-06 07:45:08

LinuxLinux內核

2021-09-28 07:12:09

Linux內核入口

2021-03-11 11:14:39

鴻蒙HarmonyOS應用

2021-04-08 09:32:17

鴻蒙HarmonyOS應用

2009-12-11 15:10:22

2021-12-29 11:51:15

Linux 內核源碼Linux 系統

2022-03-31 16:26:49

鴻蒙源碼分析進程管理

2022-04-13 11:02:12

鴻蒙事件模塊事件Event

2022-03-03 18:28:28

Harmony進程任務管理模塊

2022-03-11 20:23:14

鴻蒙源碼分析進程管理

2009-08-09 20:39:11

Linux內核虛擬環境虛擬主機

2021-02-20 06:08:07

LinuxWindows內核
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 欧美午夜激情在线 | 国产欧美精品一区二区三区 | 久久综合久久久 | 久久91精品国产 | 日本精品久久 | 日本欧美国产 | 久久国产精99精产国高潮 | 色av一区 | 日本精品久久久久久久 | 一级在线 | 久久国产精品视频 | 国产1区2区在线观看 | 福利在线观看 | 99re热精品视频 | 日韩在线观看一区二区三区 | 午夜精品久久久久久久久久久久 | 91 中文字幕| 国产成人99久久亚洲综合精品 | 在线播放中文字幕 | 亚洲一区二区视频在线观看 | 亚洲欧美综合精品久久成人 | 91精品久久久久久综合五月天 | 久久99精品久久久久久琪琪 | 爱操影视 | 欧美一区二区三区在线观看 | 欧美精品在线免费 | 韩日一区二区三区 | 久久大陆 | 免费视频一区二区 | 欧美日韩在线免费 | 一区二区三区中文 | av在线播放网站 | 国产精品伦理一区 | 国产大学生情侣呻吟视频 | 自拍偷拍小视频 | 久久久久久影院 | 精品美女在线观看 | 国产日韩精品一区二区 | 国产中文字幕在线 | 国产高清视频在线观看 | 男女羞羞视频免费 |