linux中fork函數(shù)如何使用-創(chuàng)新互聯(lián)

本篇文章為大家展示了linux中 fork函數(shù)如何使用,內(nèi)容簡明扼要并且容易理解,絕對(duì)能使你眼前一亮,通過這篇文章的詳細(xì)介紹希望你能有所收獲。

創(chuàng)新互聯(lián)是一家專注于網(wǎng)站建設(shè)、成都網(wǎng)站設(shè)計(jì)與策劃設(shè)計(jì),上街網(wǎng)站建設(shè)哪家好?創(chuàng)新互聯(lián)做網(wǎng)站,專注于網(wǎng)站建設(shè)10年,網(wǎng)設(shè)計(jì)領(lǐng)域的專業(yè)建站公司;建站業(yè)務(wù)涵蓋:上街等地區(qū)。上街做網(wǎng)站價(jià)格咨詢:18982081108

【IT168 技術(shù)】 #include ;

#include ;

main ()

{

pid_t pid;

pid=fork();

if (pid < 0)

printf("error in fork!");

else if (pid == 0)

printf("i am the child process, my process id is %dn",getpid());

else

printf("i am the parent process, my process id is %dn",getpid());

}

結(jié)果是

[root@localhost c]# ./a.out

i am the child process, my process id is 4286

i am the parent process, my process id is 4285

我就想不到為什么兩行都打印出來了,在我想來,不管pid是多少,都應(yīng)該只有一行才對(duì)

chg.s 回復(fù)于:2004-04-27 21:09:30

要搞清楚fork的執(zhí)行過程,就必須先講清楚操作系統(tǒng)中的“進(jìn)程(process)”概念。一個(gè)進(jìn)程,主要包含三個(gè)元素:

o. 一個(gè)可以執(zhí)行的程序;

o. 和該進(jìn)程相關(guān)聯(lián)的全部數(shù)據(jù)(包括變量,內(nèi)存空間,緩沖區(qū)等等);

o. 程序的執(zhí)行上下文(execution context)。

不妨簡單理解為,一個(gè)進(jìn)程表示的,就是一個(gè)可執(zhí)行程序的一次執(zhí)行過程中的一個(gè)狀態(tài)。操作系統(tǒng)對(duì)進(jìn)程的管理,典型的情況,是通過進(jìn)程表完成的。進(jìn)程表中的每一個(gè)表項(xiàng),記錄的是當(dāng)前操作系統(tǒng)中一個(gè)進(jìn)程的情況。對(duì)于單 CPU的情況而言,每一特定時(shí)刻只有一個(gè)進(jìn)程占用 CPU,但是系統(tǒng)中可能同時(shí)存在多個(gè)活動(dòng)的(等待執(zhí)行或繼續(xù)執(zhí)行的)進(jìn)程。

一個(gè)稱為“程序計(jì)數(shù)器(program counter, pc)”的寄存器,指出當(dāng)前占用 CPU的進(jìn)程要執(zhí)行的下一條指令的位置。

當(dāng)分給某個(gè)進(jìn)程的 CPU時(shí)間已經(jīng)用完,操作系統(tǒng)將該進(jìn)程相關(guān)的寄存器的值,保存到該進(jìn)程在進(jìn)程表中對(duì)應(yīng)的表項(xiàng)里面;把將要接替這個(gè)進(jìn)程占用 CPU的那個(gè)進(jìn)程的上下文,從進(jìn)程表中讀出,并更新相應(yīng)的寄存器(這個(gè)過程稱為“上下文交換(process context switch)”,實(shí)際的上下文交換需要涉及到更多的數(shù)據(jù),那和fork無關(guān),不再多說,主要要記住程序寄存器pc指出程序當(dāng)前已經(jīng)執(zhí)行到哪里,是進(jìn)程上下文的重要內(nèi)容,換出 CPU的進(jìn)程要保存這個(gè)寄存器的值,換入CPU的進(jìn)程,也要根據(jù)進(jìn)程表中保存的本進(jìn)程執(zhí)行上下文信息,更新這個(gè)寄存器)。

好了,有這些概念打底,可以說fork了。當(dāng)你的程序執(zhí)行到下面的語句:

pid=fork();

操作系統(tǒng)創(chuàng)建一個(gè)新的進(jìn)程(子進(jìn)程),并且在進(jìn)程表中相應(yīng)為它建立一個(gè)新的表項(xiàng)。新進(jìn)程和原有進(jìn)程的可執(zhí)行程序是同一個(gè)程序;上下文和數(shù)據(jù),絕大部分就是原進(jìn)程(父進(jìn)程)的拷貝,但它們是兩個(gè)相互獨(dú)立的進(jìn)程!此時(shí)程序寄存器pc,在父、子進(jìn)程的上下文中都聲稱,這個(gè)進(jìn)程目前執(zhí)行到fork調(diào)用即將返回(此時(shí)子進(jìn)程不占有CPU,子進(jìn)程的pc不是真正保存在寄存器中,而是作為進(jìn)程上下文保存在進(jìn)程表中的對(duì)應(yīng)表項(xiàng)內(nèi))。問題是怎么返回,在父子進(jìn)程中就分道揚(yáng)鑣。

父進(jìn)程繼續(xù)執(zhí)行,操作系統(tǒng)對(duì)fork的實(shí)現(xiàn),使這個(gè)調(diào)用在父進(jìn)程中返回剛剛創(chuàng)建的子進(jìn)程的pid(一個(gè)正整數(shù)),所以下面的if語句中pid<0, pid==0的兩個(gè)分支都不會(huì)執(zhí)行。所以輸出i am the parent process…

子進(jìn)程在之后的某個(gè)時(shí)候得到調(diào)度,它的上下文被換入,占據(jù) CPU,操作系統(tǒng)對(duì)fork的實(shí)現(xiàn),使得子進(jìn)程中fork調(diào)用返回0。所以在這個(gè)進(jìn)程(注意這不是父進(jìn)程了哦,雖然是同一個(gè)程序,但是這是同一個(gè)程序的另外一次執(zhí)行,在操作系統(tǒng)中這次執(zhí)行是由另外一個(gè)進(jìn)程表示的,從執(zhí)行的角度說和父進(jìn)程相互獨(dú)立)中pid=0。這個(gè)進(jìn)程繼續(xù)執(zhí)行的過程中,if語句中 pid<0不滿足,但是pid==0是true。所以輸出i am the child process…

我想你比較困惑的就是,為什么看上去程序中互斥的兩個(gè)分支都被執(zhí)行了。在一個(gè)程序的一次執(zhí)行中,這當(dāng)然是不可能的;但是你看到的兩行輸出是來自兩個(gè)進(jìn)程,這兩個(gè)進(jìn)程來自同一個(gè)程序的兩次執(zhí)行。

我的天,不知道說明白了沒……

zhaojinbo 回復(fù)于:2004-04-28 12:35:50

fork 之后,操作系統(tǒng)會(huì)復(fù)制一個(gè)與父進(jìn)程完全相同的子進(jìn)程,雖說是父子關(guān)系,但是在操作系統(tǒng)看來,他們更像兄弟關(guān)系,這2個(gè)進(jìn)程共享代碼空間,但是數(shù)據(jù)空間是互相獨(dú)立的,子進(jìn)程數(shù)據(jù)空間中的內(nèi)容是父進(jìn)程的完整拷貝,指令指針也完全相同,但只有一點(diǎn)不同,如果fork成功,子進(jìn)程中 fork的返回值是0,父進(jìn)程中fork的返回值是子進(jìn)程的進(jìn)程號(hào),如果fork不成功,父進(jìn)程會(huì)返回錯(cuò)誤。

可以這樣想象,2個(gè)進(jìn)程一直同時(shí)運(yùn)行,而且步調(diào)一致,在fork之后,他們分別作不同的工作,也就是分岔了。這也是fork為什么叫fork的原因。

至于那一個(gè)最先運(yùn)行,可能與操作系統(tǒng)有關(guān),而且這個(gè)問題在實(shí)際應(yīng)用中并不重要,如果需要父子進(jìn)程協(xié)同,可以通過原語的辦法解決。

sniper 回復(fù)于:2004-04-28 22:11:15

哦,偶明白了,在程序段里用了fork();之后程序出了分岔,派生出了兩個(gè)進(jìn)程。具體哪個(gè)先運(yùn)行就看該系統(tǒng)的調(diào)度算法了。

在這里,我們可以這么認(rèn)為,在運(yùn)行到"pid=fork();"時(shí)系統(tǒng)派生出一個(gè)跟主程序一模一樣的子進(jìn)程。該進(jìn)程的"pid=fork();"一句中pid得到的就是子進(jìn)程本身的 pid;子進(jìn)程結(jié)束后,父進(jìn)程的"pid=fork();"中pid得到的就是父進(jìn)程本身的pid。因此改程序有兩行輸出。

注:此處不準(zhǔn)確,在子進(jìn)程中pid的值為0,通過getpid可以獲取子進(jìn)程的進(jìn)程id;在父進(jìn)程中pid為父進(jìn)程編號(hào)。

勘誤:父進(jìn)程中的pid值為子進(jìn)程進(jìn)程號(hào),只有父進(jìn)程執(zhí)行的getpid()才是他自己的進(jìn)程號(hào)。寒,徹底的in了

jjl3 回復(fù)于:2004-07-14 11:43:20

我做如下修改

#include ;

#include ;

main ()

{

pid_t pid;

printf("fork!"); // printf("fork!n");

pid=fork();

if (pid < 0)

printf("error in fork!");

else if (pid == 0)

printf("i am the child process, my process id is %dn",getpid());

else

printf("i am the parent process, my process id is %dn",getpid());

}

結(jié)果是

[root@localhost c]# ./a.out

fork!i am the child process, my process id is 4286

fork!i am the parent process, my process id is 4285

但我改成printf("fork!n");后,結(jié)果是

[root@localhost c]# ./a.out

fork!

i am the child process, my process id is 4286

i am the parent process, my process id is 4285

為什么只有一個(gè)fork!打印出來了?上一個(gè)為什么有2個(gè)?

bashfulboy 回復(fù)于:2004-07-14 22:10:52

我也來一下:

wujiajia 的理解有些錯(cuò)誤,

printf("AAAAAAAA");//print 一次; 這里會(huì)print 2次

如果你將 printf("AAAAAA") 換成 printf("AAAAAAn") 那么就是只打印一次了。

主要的區(qū)別是因?yàn)橛辛艘粋€(gè) n 回車符號(hào)

這就跟Printf的緩沖機(jī)制有關(guān)了,printf某些內(nèi)容時(shí),操作系統(tǒng)僅僅是把該內(nèi)容放到了stdout的緩沖隊(duì)列里了,并沒有實(shí)際的寫到屏幕上

但是,只要看到有 n 則會(huì)立即刷新stdout,因此就馬上能夠打印了。

運(yùn)行了printf("AAAAAA") 后, AAAAAA 僅僅被放到了緩沖里,再運(yùn)行到fork時(shí),緩沖里面的 AAAAAA 被子進(jìn)程繼承了

因此在子進(jìn)程度stdout緩沖里面就也有了 AAAAAA.

所以,你最終看到的會(huì)是 AAAAAA 被printf了2次!!!!

而運(yùn)行 printf("AAAAAAn")后, AAAAAA 被立即打印到了屏幕上,之后fork到的子進(jìn)程里的stdout緩沖里不會(huì)有 AAAAAA 內(nèi)容

因此你看到的結(jié)果會(huì)是 AAAAAA 被printf了1次!!!!

(精要)

albcamus 回復(fù)于:2005-03-08 15:56:11

>;>;派生子進(jìn)程的pid變量并沒有被改變是什么意思 對(duì)于子進(jìn)程來講pid不就是0嗎

1,派生子進(jìn)程的進(jìn)程,即父進(jìn)程,其pid不變;

2,對(duì)子進(jìn)程來說,fork返回給它0,但它的pid絕對(duì)不會(huì)是0;之所以fork返回0給它,是因?yàn)樗S時(shí)可以調(diào)用getpid()來獲取自己的pid;

3,樓上的樓上的你的觀點(diǎn)是對(duì)的,fork之后夫子進(jìn)程除非采用了同步手段,否則不能確定誰先運(yùn)行,也不能確定誰先結(jié)束。認(rèn)為子進(jìn)程結(jié)束后父進(jìn)程才從fork返回的,這是不對(duì)的,fork不是這樣的,vfork才這樣。VFORK調(diào)用結(jié)束后,父進(jìn)程處于非可中斷狀態(tài),直到子進(jìn)程運(yùn)行結(jié)束返回。

上述內(nèi)容就是linux中 fork函數(shù)如何使用,你們學(xué)到知識(shí)或技能了嗎?如果還想學(xué)到更多技能或者豐富自己的知識(shí)儲(chǔ)備,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道。

文章標(biāo)題:linux中fork函數(shù)如何使用-創(chuàng)新互聯(lián)
當(dāng)前URL:http://www.muchs.cn/article34/dhjspe.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站收錄、響應(yīng)式網(wǎng)站定制網(wǎng)站、做網(wǎng)站、品牌網(wǎng)站建設(shè)自適應(yīng)網(wǎng)站

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

成都app開發(fā)公司