




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
1、fork簡介:fork英文原意是分岔,分支”的意思,而在操作系統(tǒng)中,乃是著名的Unix(或類Unix,如Linux.Minix)中用于創(chuàng)建子進(jìn)程的系統(tǒng)調(diào)用?!綨OTE1】fork()的作用是什么?換句話說,你用fork()的目的是什么?一一是為了產(chǎn)生一個(gè)新的進(jìn)程,地球人都知道:)產(chǎn)生一個(gè)什么樣的進(jìn)程?一一和你本來調(diào)用fork()的那個(gè)進(jìn)程基本一樣的進(jìn)程,其實(shí)就是你原來進(jìn)程的副本;真的完全一樣嗎?當(dāng)然不能完全一樣,你要兩個(gè)除了pid之外其它一模一樣的進(jìn)程干什么,就算memory再多也不用這么擺譜吧?哪里不一樣?一一當(dāng)然最重要的是fork()之后執(zhí)行的代碼不一樣,youknow,iknow:)怎么
2、實(shí)現(xiàn)呢?如果是Windows,它會讓你在fork()里面提供一大堆東西,指明這個(gè)那個(gè)什么的我用的是unix啊一一所以很簡單,unix會讓兩個(gè)進(jìn)程(不錯(cuò),原來是一個(gè),unix替你復(fù)制了一個(gè),現(xiàn)在有兩個(gè))在fork()之后產(chǎn)生不同:返回值不同。其中一個(gè)進(jìn)程(使用新的pid)里面的fork()返回零,這個(gè)進(jìn)程就是子進(jìn)程”;而另一個(gè)進(jìn)程(使用原來的pid)中的fork()返回前面那個(gè)子進(jìn)程的pid,他自己被稱為“父進(jìn)程”然后呢?一一寫代碼的人又不笨,當(dāng)然就根據(jù)返回值是否非零來判斷了,現(xiàn)在我是在子進(jìn)程里面呢,還是在父進(jìn)程里面?在子進(jìn)程里面就執(zhí)行子進(jìn)程該執(zhí)行的代碼,在父進(jìn)程里面就執(zhí)行父進(jìn)程的代碼有鐵桿wi
3、ndowsfans借此說明,windows好啊,子進(jìn)程用子進(jìn)程的代碼,父進(jìn)程用父進(jìn)程的,你unix笨了吧,子進(jìn)程包含父進(jìn)程、子進(jìn)程的代碼,父進(jìn)程包含父進(jìn)程子進(jìn)程的代碼,豈不是多占用內(nèi)存了嗎?據(jù)我所知,unix代碼段都是可重入代碼,也就是說,進(jìn)程復(fù)制,并不復(fù)制代碼段,若干個(gè)進(jìn)程共享同一代碼段,增加的只是全局共享數(shù)據(jù)和對文件描述符的引用等,另外就是堆棧。你一個(gè)代碼長達(dá)10M的進(jìn)程,fork()出三四個(gè)子進(jìn)程,只是增加一點(diǎn)內(nèi)存占用(如果你沒有使用很多全局變量的話),而不是占用40M以上的內(nèi)存?!綨OTE2】程序從fork開始分支(稱分支不準(zhǔn)確),一路是主進(jìn)程pid0(pid是子進(jìn)程ID)路是子進(jìn)程p
4、id=0自此分成兩個(gè)任務(wù)其實(shí)fork的時(shí)候已經(jīng)兩個(gè)分支了,數(shù)據(jù)段被復(fù)制了一份,因此pid有兩份執(zhí)行pid=fork()時(shí),返回值賦給pid在兩個(gè)進(jìn)程中運(yùn)行,fork會返回給父進(jìn)程的那個(gè)0的值,告訴調(diào)用者新建進(jìn)程的pid子進(jìn)程的fork返回值是0更不用說if.else的比較也是在兩個(gè)進(jìn)程中都做的了【NOTE3】fork的精辟剖析程序如下:#include;#include;main()pid_tpid;pid=fork();if(pidpid_tfork();當(dāng)一個(gè)進(jìn)程調(diào)用了fork以后,系統(tǒng)會創(chuàng)建一個(gè)子進(jìn)程這個(gè)子進(jìn)程和父進(jìn)程不同的地方只有他的進(jìn)程ID和父進(jìn)程ID,其他的都是一樣就象父進(jìn)程克隆(
5、clone)自己一樣當(dāng)然創(chuàng)建兩個(gè)一模一樣的進(jìn)程是沒有意義的為了區(qū)分父進(jìn)程和子進(jìn)程,我們必須跟蹤fork的返回值.當(dāng)fork掉用失敗的時(shí)候(內(nèi)存不足或者是用戶的最大進(jìn)程數(shù)已到)fork返回-1,否則fork的返回值有重要的作用對于父進(jìn)程fork返回子進(jìn)程的ID,而對于fork子進(jìn)程返回0我們就是根據(jù)這個(gè)返回值來區(qū)分父子進(jìn)程的.父進(jìn)程為什么要創(chuàng)建子進(jìn)程呢?前面我們已經(jīng)說過了Linux是一個(gè)多用戶操作系統(tǒng),在同一時(shí)間會有許多的用戶在爭奪系統(tǒng)的資源.有時(shí)進(jìn)程為了早一點(diǎn)完成任務(wù)就創(chuàng)建子進(jìn)程來爭奪資源.一旦子進(jìn)程被創(chuàng)建,父子進(jìn)程一起從fork處繼續(xù)執(zhí)行,相互競爭系統(tǒng)的資源.有時(shí)候我們希望子進(jìn)程繼續(xù)執(zhí)行,而
6、父進(jìn)程阻塞,直到子進(jìn)程完成任務(wù).這個(gè)時(shí)候我們可以調(diào)用wait或者waitpid系統(tǒng)調(diào)用.總結(jié)一下有三:派生子進(jìn)程的進(jìn)程,即父進(jìn)程,其pid不變;對子進(jìn)程來說,fork返回給它0,但它的pid絕對不會是0;之所以fork返回0給它,是因?yàn)樗S時(shí)可以調(diào)用getpid()來獲取自己的pid;fork之后父子進(jìn)程除非采用了同步手段,否則不能確定誰先運(yùn)行,也不能確定誰先結(jié)束。認(rèn)為子進(jìn)程結(jié)束后父進(jìn)程才從fork返回的,這是不對的,fork不是這樣的,vfork才這樣。【NOTE4】首先必須有一點(diǎn)要清楚,函數(shù)的返回值是儲存在寄存器eax中的。其次,當(dāng)fork返回時(shí),新進(jìn)程會返回0是因?yàn)樵诔跏蓟蝿?wù)結(jié)構(gòu)時(shí),將
7、eax設(shè)置為0;在fork中,把子進(jìn)程加入到可運(yùn)行的隊(duì)列中,由進(jìn)程調(diào)度程序在適當(dāng)?shù)臅r(shí)機(jī)調(diào)度運(yùn)行。也就是從此時(shí)開始,當(dāng)前進(jìn)程分裂為兩個(gè)并發(fā)的進(jìn)程。無論哪個(gè)進(jìn)程被調(diào)度運(yùn)行,都將繼續(xù)執(zhí)行fork函數(shù)的剩余代碼,執(zhí)行結(jié)束后返回各自的值?!綨OTE5】對于fork來說,父子進(jìn)程共享同一段代碼空間,所以給人的感覺好像是有兩次返回,其實(shí)對于調(diào)用fork的父進(jìn)程來說,如果fork出來的子進(jìn)程沒有得到調(diào)度,那么父進(jìn)程從fork系統(tǒng)調(diào)用返回,同時(shí)分析sys_fork知道,fork返回的是子進(jìn)程的id。再看fork出來的子進(jìn)程,由copy_process函數(shù)可以看出,子進(jìn)程的返回地址為ret_from_fork(和
8、父進(jìn)程在同一個(gè)代碼點(diǎn)上返回),返回值直接置為0。所以當(dāng)子進(jìn)程得到調(diào)度的時(shí)候,也從fork返回,返回值為0。關(guān)鍵注意兩點(diǎn):l.fork返回后,父進(jìn)程或子進(jìn)程的執(zhí)行位置。(首先會將當(dāng)前進(jìn)程eax的值做為返回值)2.兩次返回的pid存放的位置(eax中)進(jìn)程調(diào)用copy_process得到lastpid的值(放入eax中,fork正常返回后,父進(jìn)程中返回的就是lastpid)子進(jìn)程任務(wù)狀態(tài)段tss的eax被設(shè)置成0,fork.c中p-tss.eax=0;(如果子進(jìn)程要執(zhí)行就需要進(jìn)程切換,當(dāng)發(fā)生切換時(shí),子進(jìn)程tss中的eax值就調(diào)入eax寄存器,子進(jìn)程執(zhí)行時(shí)首先會將eax的內(nèi)容做為返回值)當(dāng)子進(jìn)程開始
9、執(zhí)行時(shí),copy_process返回eax的值。fork()后,就是兩個(gè)任務(wù)同時(shí)進(jìn)行,父進(jìn)程用他的tss,子進(jìn)程用自己的tss,在切換時(shí),各用各的eax中的值.所以,“一次調(diào)用兩次返回”是2個(gè)不同的進(jìn)程!看這一句:pid=fork()當(dāng)執(zhí)行這一句時(shí),當(dāng)前進(jìn)程進(jìn)入fork()運(yùn)行,此時(shí),fork()內(nèi)會用一段嵌入式匯編進(jìn)行系統(tǒng)調(diào)用:int0 x80(具體代碼可參見內(nèi)核版本0.11的unistd.h文件的133行_syscall0函數(shù))。這時(shí)進(jìn)入內(nèi)核根據(jù)此前寫入eax的系統(tǒng)調(diào)用功能號便會運(yùn)行sys_fork系統(tǒng)調(diào)用。接著,sys_fork中首先會調(diào)用C函數(shù)find_empty_process產(chǎn)生一
10、個(gè)新的進(jìn)程,然后會調(diào)用C函數(shù)copy_process將父進(jìn)程的內(nèi)容復(fù)制給子進(jìn)程,但是子進(jìn)程tss中的eax值賦值為0(這也是為什么子進(jìn)程中返回0的原因),當(dāng)賦值完成后,copy_process會返回新進(jìn)程(該子進(jìn)程)的pid,這個(gè)值會被保存到eax中。這時(shí)子進(jìn)程就產(chǎn)生了,此時(shí)子進(jìn)程與父進(jìn)程擁有相同的代碼空間,程序指針寄存器eip指向相同的下一條指令地址,當(dāng)fork正常返回調(diào)用其的父進(jìn)程后,因?yàn)閑ax中的值是新創(chuàng)建的子進(jìn)程號,所以,fork()返回子進(jìn)程號,執(zhí)行else(pid0);當(dāng)產(chǎn)生進(jìn)程切換運(yùn)行子進(jìn)程時(shí),首先會恢復(fù)子進(jìn)程的運(yùn)行環(huán)境即裝入子進(jìn)程的tss任務(wù)狀態(tài)段,其中的eax值(copy_p
11、rocess中置為0)也會被裝入eax寄存器,所以,當(dāng)子進(jìn)程運(yùn)行時(shí),fork返回的是0執(zhí)行if(pid=0)?!綨OTE5】理解它關(guān)鍵在于理解堆棧的切換和壓棧,彈棧!關(guān)于子進(jìn)程的返回:子進(jìn)程復(fù)制了父進(jìn)程的棧內(nèi)容,從高到低SSESPEFLAGSCSEIP-此是int0 x80的下一條指令,也是子進(jìn)程開始執(zhí)行的地方DSESFSEDXECXEBXGSESIEDIEBPEAX(0)由于EAX=0,所以子進(jìn)程返回0給fork.注:新進(jìn)程的用戶棧設(shè)為其父進(jìn)程的用戶棧(最后彈出的SS,ESP)。如果父子進(jìn)程以copy_on_write方式共用用戶堆棧(Linux之下就是這樣的),而且在此之前父進(jìn)程修改了該堆
12、棧(如果父進(jìn)程先返回,這幾乎是肯定的),那么,系統(tǒng)已經(jīng)為父進(jìn)程創(chuàng)建了該用戶棧的副本,父進(jìn)程原來的用戶棧留給了子進(jìn)程。那么新進(jìn)程的系統(tǒng)棧已經(jīng)清空,新進(jìn)程回到了用戶態(tài),返回到了函數(shù)fork?!綨OTE6】關(guān)于fork的討論與評價(jià):fork好不好?相比其他操作系統(tǒng)如Windows.Windows會有諸如CreateProcess這樣的函數(shù)來創(chuàng)建一個(gè)與生俱來兩手空空的獨(dú)立的新進(jìn)程。然后還有一大堆參數(shù),指手畫腳的告訴你這個(gè)那個(gè)是什么。煩K.I.S.S.(Keepitsimple,stupid.)是Unix的至高原則。fork起源于Unix操作系統(tǒng)。那是貝爾實(shí)驗(yàn)室的K&R(這兩人是Unix和C語言之父)的一項(xiàng)天才發(fā)明Linux由于與生俱來就與Unix血濃于水,所以繼承了它的這個(gè)天才發(fā)明。這種方法效率是很高的。因?yàn)閺?fù)制的代價(jià)是很低的。在計(jì)算機(jī)網(wǎng)絡(luò)的實(shí)現(xiàn)中,以及在client/server系統(tǒng)中的server一方的實(shí)現(xiàn)中,fork常常是最自然,最有效,最適宜的手段。很多人甚至懷疑,到底是先有fork還是
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 船舶保養(yǎng)考試題及答案
- 2025年軍隊(duì)文職人員招聘之軍隊(duì)文職法學(xué)考前沖刺試卷A卷含答案
- 小升初科學(xué)測試題及答案
- 2019-2025年消防設(shè)施操作員之消防設(shè)備基礎(chǔ)知識能力檢測試卷B卷附答案
- 2019-2025年消防設(shè)施操作員之消防設(shè)備基礎(chǔ)知識模考模擬試題(全優(yōu))
- 2019-2025年消防設(shè)施操作員之消防設(shè)備基礎(chǔ)知識基礎(chǔ)試題庫和答案要點(diǎn)
- 社保知識培訓(xùn)課件北京
- 語文小說文本解讀技巧訓(xùn)練教案:以小說圍城為例
- 辦公室人員基本信息表
- 寫作技巧大揭秘:高中語文作文指導(dǎo)課程教案
- 2025年共青科技職業(yè)學(xué)院單招職業(yè)適應(yīng)性測試題庫完整版
- 2025年上半年潛江市城市建設(shè)發(fā)展集團(tuán)招聘工作人員【52人】易考易錯(cuò)模擬試題(共500題)試卷后附參考答案
- 統(tǒng)編版語文二年級下冊15古詩二首 《曉出凈慈寺送林子方》公開課一等獎創(chuàng)新教學(xué)設(shè)計(jì)
- 旅游電子商務(wù)(第2版) 課件全套 周春林 項(xiàng)目1-8 電子商務(wù)概述-旅游電子商務(wù)數(shù)據(jù)挖掘
- 2025年安徽警官職業(yè)學(xué)院單招職業(yè)適應(yīng)性測試題庫帶答案
- 廣東廣東省錢幣學(xué)會招聘筆試歷年參考題庫附帶答案詳解
- 2025年福建省中職《英語》學(xué)業(yè)水平考試核心考點(diǎn)試題庫500題(重點(diǎn))
- 2024年江西應(yīng)用工程職業(yè)學(xué)院單招職業(yè)技能測試題庫標(biāo)準(zhǔn)卷
- 2023《住院患者身體約束的護(hù)理》團(tuán)體標(biāo)準(zhǔn)解讀PPT
- 星巴克運(yùn)營管理手冊
- 人教鄂教版小學(xué)科學(xué)三年級下冊全冊教案教學(xué)設(shè)計(jì)
評論
0/150
提交評論