資源描述:
《linux內(nèi)核設(shè)計(jì)與實(shí)現(xiàn)》由會員上傳分享,免費(fèi)在線閱讀,更多相關(guān)內(nèi)容在工程資料-天天文庫。
1、進(jìn)程管理一、FORK()函數(shù)的兩次返回的具體情況對于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(和父進(jìn)程在同一個(gè)代碼點(diǎn)上返冋),返冋值肓接置為0。所以當(dāng)了進(jìn)程得到調(diào)度的時(shí)候,也從fork返回,返回值為0?關(guān)鍵注
2、意兩點(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)程開始執(zhí)彳亍吋,copy_pro
3、cess返回eax的值。fork()后,就是兩個(gè)任務(wù)同時(shí)進(jìn)行,父進(jìn)程用他的tss,子進(jìn)程用白己的tss,在切換時(shí),各用各的eax中的值.所以,"一次調(diào)用兩次返回”是2個(gè)不同的進(jìn)程!例子:intmain(){pid_tpid;pid=fork();if(pid<0){fprintf(stderr,"ForkFailed,z);exit(-1);}elseif(pid==0){printf("ch訂dprocess");}else{printf("parentprocess");return0;這個(gè)程序執(zhí)
4、行為什么總是顯示:chiIdprocessparentprocess而不會先是parent示是ch訂d呢?答:看這一句: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)用:int0x80(具體代碼可參見內(nèi)核版本0.11的unistd.h文件的133行_syscal10函數(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_proccss產(chǎn)綸一個(gè)新的進(jìn)程,然
5、后會調(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)程)的linux進(jìn)程描述符一task_struct結(jié)構(gòu)為了管理進(jìn)程,操作系統(tǒng)必須對每個(gè)進(jìn)程所做的事悄進(jìn)行清楚地描述,為此,操作系統(tǒng)使用數(shù)據(jù)結(jié)構(gòu)來代表處理不同的實(shí)體,這個(gè)數(shù)據(jù)結(jié)構(gòu)就是通常所說的進(jìn)程描述符或進(jìn)程控制塊,在lirrnx系統(tǒng)中,這就是taskstruct結(jié)構(gòu),在includelinuxsched.h文件中定
6、義。每個(gè)進(jìn)程都會被分配一個(gè)task_struct結(jié)構(gòu),它包含了這個(gè)進(jìn)程的所有信息,在任何時(shí)候操作系統(tǒng)都能跟蹤這個(gè)結(jié)構(gòu)的信息,這個(gè)結(jié)構(gòu)是linux內(nèi)核匯總最重要的數(shù)據(jù)結(jié)構(gòu),下面我們會詳細(xì)的介紹。這個(gè)結(jié)構(gòu)的源代碼及其注釋如下,Z后對其進(jìn)行了分類解禪。//進(jìn)程描述符taskstructstructtaskstruct{/**offsetsofthesearehardcodedelsewhere-touchwithcare*/volati1elongstate;/*Tunrunnable,0runnable,>0stop
7、ped*///-l不能運(yùn)行0運(yùn)行>0停止unsignedlongflags;/*perprocessflags,definedbelow*///進(jìn)程標(biāo)志,在下面定義intsigpending;//進(jìn)程上是否有待處理的信號mm_segment_taddr_limit;/*threadaddressspace:進(jìn)程地址空間O-OxBFFFFFFFforuser-thead0-OxFFFFFFFFforkernel-thread*/volatilelongneed_resched;//調(diào)度標(biāo)丿忐,表示該進(jìn)程是否需要重新
8、調(diào)度,若非0,則當(dāng)從內(nèi)核態(tài)返回到用八態(tài),會發(fā)生調(diào)度intlock_depth;/*Lockdepth*///鎖深度/**offset32beginshereon32-bitplatforms?Wekeep*al1fieldsinasinglecachelinethatareneededfor*thegoodness()loopinscheduleO.*/longcount