fork()函式的兩次返回的具體情況
對於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個不同的程序!
例子:int main()
else
if ( pid == 0 )
else
return 0;
} 這個程式執行為什麼總是顯示:child process
parent process
而不會先是parent 後是child呢?
答:看這一句:pid=fork()
當 執行這一句時,當前程序進入fork()執行,此時,fork()內會用一段嵌入式彙編進行系統呼叫:int 0x80(具體**可參見核心版本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)。
先顯示child process應該和核心機制有關,當fork乙個新的程序後都會進行程序的重新排程,此時總是子程序先執行(和程序優先順序有關?)
fork()函式兩次返回
為什麼fork會返回兩次?由於在複製時複製了 父程序的 堆疊段,所以兩個程序都停留在fork函式中,等待返回。因此fork函式會返回兩次,一次是在父程序中返回,另一次是在子程序中返回,這兩次的返回值是不一樣的。過程如下圖。fork呼叫的乙個奇妙之處就是它僅僅被呼叫一次,卻能夠返回兩次,它可能有三種不...
一次fork與兩次fork的區別
在講一次fork和兩次fork之前,有必要先來簡單講解一下wait的作用 1 阻塞當前程序 2 獲得子程序退出的相關資訊 殭屍程序 子程序不返回,父程序後邊的內容就沒法執行。注 wait函式只能在有子程序的父程序中呼叫。我們使用fork 函式建立乙個子程序出來往往是為了父子程序能夠同時執行兩段 如果...
建立程序時,為什麼fork會返回兩次?
為什麼fork會返回兩次?由於在複製時複製了 父程序的 堆疊段,所以兩個程序都停留在fork函式中,等待返回。因此fork函式會返回兩次,一次是在父程序中返回,另一次是在子程序中返回,這兩次的返回值是不一樣的。過程如下圖。fork呼叫的乙個奇妙之處就是它僅僅被呼叫一次,卻能夠返回兩次,它可能有三種不...