fork原理分析

2021-05-09 22:23:01 字數 1950 閱讀 5470

note4】

首先必須有一點要清楚,函式的返回值是儲存在暫存器eax中的。

其次,當fork返回時,新程序會返回0是因為在初始化任務結構時,將eax設定為0;

在fork中,把子程序加入到可執行的佇列中,由程序排程程式在適當的時機排程執行。也就是從此時開始,當前程序**為兩個併發的程序。

無論哪個程序被排程執行,都將繼續執行fork函式的剩餘**,執行結束後返回各自的值。

【note5】

對於fork來說,父子程序共享同一段**空間,所以給人的感覺好像是有兩次返回,其實對於呼叫fork的父程序來說,如果fork出來的子程序沒有得到 排程,那麼父程序從fork系統呼叫返回,同時分析sys_fork知道,fork返回的是子程序的id。再看fork出來的子程序,由 copy_process函式可以看出,子程序的返回位址為ret_from_fork(和父程序在同乙個**點上返回),返回值直接置為0。所以當子進 程得到排程的時候,也從fork返回,返回值為0。

關鍵注意兩點:1.fork返回後,父程序或子程序的執行位置。(首先會將當前程序eax的值做為返回值)2.兩次返回的pid存放的位置。(eax中)

程序呼叫copy_process得到lastpid的值(放入eax中,fork正常返回後,父程序中返回的就是lastpid)

子程序任務狀態段tss的eax被設定成0,

fork.c 中

p->tss.eax=0;(如果子程序要執行就需要程序切換,當發生切換時,子程序tss中的eax值就調入eax暫存器,子程序執行時首先會將eax的內容做為返回值)

當子程序開始執行時,copy_process返回eax的值。

fork()後,就是兩個任務同時進行,父程序用他的tss,子程序用自己的tss,在切換時,各用各的eax中的值.

所以,「一次呼叫兩次返回」是2個不同的程序!

看這一句:pid=fork()

當執行這一句時,當前程序進入fork()執行,此時,fork()內會用一段嵌入式彙編進行系統呼叫:int 0×80(具體**可參見核心版本0.11的unistd.h檔案的133行_syscall0函式)。這時進入核心根據此前寫入eax的系統呼叫功能號 便會執行sys_fork系統呼叫。接著,sys_fork中首先會呼叫c函式find_empty_process產生乙個新的程序,然後會呼叫c函式 copy_process將父程序的內容複製給子程序,但是子程序tss中的eax值賦值為0(這也是為什麼子程序中返回0的原因),當賦值完成 後,copy_process會返回新程序(該子程序)的pid,這個值會被儲存到eax中。這時子程序就產生了,此時子程序與父程序擁有相同的**空 間,程式指標暫存器eip指向相同的下一條指令位址,當fork正常返**用其的父程序後,因為eax中的值是新建立的子程序號,所以,fork()返回 子程序號,執行else(pid>0);當產生程序切換執行子程序時,首先會恢復子程序的執行環境即裝入子程序的tss任務狀態段,其中的 eax值(copy_process中置為0)也會被裝入eax暫存器,所以,當子程序執行時,fork返回的是0執行if(pid==0)。

【note5】

理解它關鍵在於理解堆疊的切換和壓棧,彈棧!

關於子程序的返回:

子程序複製了父程序的棧內容,從高到低

ssesp

eflags

cseip 此是int 0×80 的下一條指令,也是子程序開始執行的地方!!!!

dses

fsedx

ecxebx

gsesi

ediebp

eax(0)

由於 eax = 0,所以子程序返回 0 給 fork.

注:新程序的使用者棧設為其父程序的使用者棧(最後彈出的ss,esp)。如果父子程序以copy_on_write方式共用使用者堆疊

(linux之下就是這樣的),而且在此之前父程序修改了該堆疊(如果父程序先返回,這幾乎是肯定的),那麼,系統已經為父程序建立了該使用者棧的副本,父程序原來的使用者棧留給了子程序。那麼新程序的系統棧已經清空,新程序回到了使用者態,返回到了函式fork。

Git原理及實踐(Fork模式)

git是目前最先進的分布式版本控制系統,在git的管理下,每個人的電腦上都有乙個完整的版本庫,配合雲上一台充當 伺服器 的電腦 方便交換和修改 git是用於記錄檔案變更的版本控制系統,支援檔案版本跟蹤,記錄,回退,合併等操作,並在此基礎上實現了版本切換,差異比較,分支管理,分布式協作等功能。keyw...

Linux核心 fork 原始碼分析

核心版本 linux 4.4.18 原始碼位置 這裡 接著 呼叫copy process 它設定了程序描述符以及子程序所需的任何其他核心資料結構。ftrace graph init task 初始化ftrace,核心追蹤函式呼叫。rt mutex init task 初始化鎖。copy creds ...

Linux中fork函式分析

乙個程序,是包括 資料和分配給程序的資源,fork 函式通過系統呼叫建立乙個與原來程序幾乎完全相同的程序,也就兩個程序可以完全做相同的事,但如果初始化引數或者傳入的變數不同,兩個程序也可以做不同的事 乙個程序呼叫fork 函式後,系統先給新的程序分配資源,例如儲存資料和 的空間。然後把原來的程序的所...