久久精品人人爽,华人av在线,亚洲性视频网站,欧美专区一二三

如何分析Linux內(nèi)核源碼do

170次閱讀
沒有評論

共計 2382 個字符,預(yù)計需要花費 6 分鐘才能閱讀完成。

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

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

推送會淺談一下在進(jìn)程創(chuàng)建過程中扮演著重要角色的 do_fork 函數(shù)。

內(nèi)核如何來抽象一個進(jìn)程

內(nèi)核通過一個叫做 task_struct 的結(jié)構(gòu)體來抽象一個進(jìn)程,該結(jié)構(gòu)體的定義 (以內(nèi)核 2.6 為例) 在 include/linux.sched.h 中。

截取部分 task_struct 如下:

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

do_fork 簡單分析  

接觸 linuxC 編程的人都知道,創(chuàng)建一個進(jìn)程我們需要調(diào)用 fork 函數(shù),fork 其實又是調(diào)用了 clone 函數(shù)來實現(xiàn)的,而 clone 函數(shù)中最關(guān)鍵的函數(shù)就是 do_fork 函數(shù)。

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

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

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

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

參數(shù)如下: 

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

2.stack_start: 子進(jìn)程用戶態(tài)堆棧的開始地址;

3.regs: 當(dāng)系統(tǒng)發(fā)生系統(tǒng)調(diào)用時,需從用戶態(tài)切換到內(nèi)核態(tài),此結(jié)構(gòu)體用來保存此時用戶態(tài)進(jìn)程中的通用寄存器中的值,并被存放在內(nèi)核態(tài)堆棧中;

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

5.parent_tidptr: 父進(jìn)程在用戶態(tài)下 pid 的地址;

6.child_tidptr: 子進(jìn)程在用戶態(tài)下 pid 的地址;

其中 clone_flags 的標(biāo)志位宏定義如下: 

舉個簡單的例子當(dāng)我們的參數(shù)中設(shè)置了 CLONE_VM 這個宏,那么就以為這我們新創(chuàng)建的進(jìn)程和其父進(jìn)程要共享 VM,當(dāng)我們設(shè)置了 CLONE_FILES 時意味這父子進(jìn)程之間共享打開的文件描述符。

do_fork 開始執(zhí)行后首先做的就是為子進(jìn)程定義一個新的 task_struct 指針:

struct task_struct *p;

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

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

上述中不允許同時既設(shè)置了 CLONE_NEWUSER 標(biāo)志,還設(shè)置 CLONE_THREAD 標(biāo)志,這樣就會產(chǎn)生錯誤。

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

1)調(diào)用 dup_task_struct 函數(shù)為新的進(jìn)程創(chuàng)建一個內(nèi)核棧,thread_info 結(jié)構(gòu)和 task_struct 等,當(dāng)然此時的值都是和父進(jìn)程完全一樣的

dup_task_struct 函數(shù)定義如下:

2)檢查并確保新創(chuàng)建該子進(jìn)程后,當(dāng)前用戶所擁有的進(jìn)程數(shù)沒有超出給它分配的資源限制,代碼如下: 

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

 

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

sched_fork(p, clone_flags);

5) 接著就是子進(jìn)程拷貝父進(jìn)程的一些資源,具體如下,調(diào)用 copy_files 函數(shù)拷貝父進(jìn)程打開的文件描述符: 

調(diào)用 copy_fs 繼承父進(jìn)程所屬的文件系統(tǒng)。 

調(diào)用 copy_signal 函數(shù)拷貝并設(shè)置新的 signal_struct,signal_struct 包含了大量的進(jìn)程運(yùn)行的信息,調(diào)用 copy_mm 函數(shù)處理與新進(jìn)程的內(nèi)存問題。 

調(diào)用 copy_io 函數(shù)拷貝父進(jìn)程的 I / O 情況:

 

還有調(diào)用 copy_namespaces 和 copy_thread 等,這里就不在贅述。

6)調(diào)用 alloc_pid 為新進(jìn)程分配一個 pid。

pid = alloc_pid(p- nsproxy- pid_ns);

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

 

總結(jié)

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

上述內(nèi)容就是如何分析 Linux 內(nèi)核源碼 do_fork,你們學(xué)到知識或技能了嗎?如果還想學(xué)到更多技能或者豐富自己的知識儲備,歡迎關(guān)注丸趣 TV 行業(yè)資訊頻道。

正文完
 
丸趣
版權(quán)聲明:本站原創(chuàng)文章,由 丸趣 2023-08-25發(fā)表,共計2382字。
轉(zhuǎn)載說明:除特殊說明外本站除技術(shù)相關(guān)以外文章皆由網(wǎng)絡(luò)搜集發(fā)布,轉(zhuǎn)載請注明出處。
評論(沒有評論)
主站蜘蛛池模板: 灵石县| 黄梅县| 航空| 铁岭县| 武山县| 广河县| 东源县| 新郑市| 湖口县| 大同市| 赤壁市| 怀宁县| 松阳县| 浏阳市| 于田县| 南江县| 景东| 桐庐县| 广东省| 平凉市| 楚雄市| 曲阜市| 龙陵县| 军事| 苏州市| 临夏县| 贺兰县| 巩义市| 胶南市| 石渠县| 台前县| 醴陵市| 商南县| 石台县| 杭锦后旗| 溆浦县| 奉新县| 双柏县| 曲松县| 株洲市| 长治县|