一区二区三区日韩精品-日韩经典一区二区三区-五月激情综合丁香婷婷-欧美精品中文字幕专区

分享

關于fork的討論

 todaytomo 2007-02-10

fork的一個例子,好像人家是講得很詳細了,我還是不明白


http://Tech. 05年09月13日 19:28 ChinaUnix.net
#include <unistd.h>
#include <sys/types.h>

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 %d\n",getpid());
        else
                printf("i am the parent process, my process id is %d\n",getpid());
}

結果是
[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是多少,都應該只有一行才對

 naiza 回復于:2004-04-23 11:38:11
這里的if和else不是以前理解的選擇分支。fork后產生的子進程和父進程并行運行的

 sashow 回復于:2004-04-23 13:41:16
[quote:7b2607dafc="naiza"]這里的if和else不是以前理解的選擇分支。fork后產生的子進程和父進程并行運行的[/quote:7b2607dafc]

這種理解是不正確的。if 和 else 還是選擇分支。

主要的原因是,[color=red:7b2607dafc]fork() 函數調用一次,返回兩次。[/color:7b2607dafc]兩次返回的區(qū)別是:子進程的返回值是0,父進程返回值為新子進程的進程ID。

 ccf 回復于:2004-04-23 14:38:59
但是只有一個pid=fork(); 呀,fork()返回的第二次值在什么時候賦給pid呢

 victory7 回復于:2004-04-27 18:06:29
這是由系統(tǒng)來控制fork地返回的

 davidtian 回復于:2004-04-27 18:11:20
fork后,父子進程共用程序段

 birdielu 回復于:2004-04-27 18:56:54
恩, 分析的很精辟

 lenovo 回復于:2004-04-27 20:09:20
[quote:d347015cc8="ccf"]但是只有一個pid=fork(); 呀,fork()返回的第二次值在什么時候賦給pid呢[/quote:d347015cc8]
pid這個變量是有兩個的,
父進程一個,
子進程一個。

 chg.s 回復于:2004-04-27 21:09:30
要搞清楚fork的執(zhí)行過程,就必須先講清楚操作系統(tǒng)中的“進程(process)”概念。一個進程,主要包含三個元素:

o. 一個可以執(zhí)行的程序;
o. 和該進程相關聯的全部數據(包括變量,內存空間,緩沖區(qū)等等);
o. 程序的執(zhí)行上下文(execution context)。

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

一個稱為“程序計數器(program counter, pc)”的寄存器,指出當前占用 CPU的進程要執(zhí)行的下一條指令的位置。

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

好了,有這些概念打底,可以說fork了。當你的程序執(zhí)行到下面的語句:
pid=fork(); 
操 作系統(tǒng)創(chuàng)建一個新的進程(子進程),并且在進程表中相應為它建立一個新的表項。新進程和原有進程的可執(zhí)行程序是同一個程序;上下文和數據,絕大部分就是原 進程(父進程)的拷貝,但它們是兩個相互獨立的進程!此時程序寄存器pc,在父、子進程的上下文中都聲稱,這個進程目前執(zhí)行到fork調用即將返回(此時 子進程不占有CPU,子進程的pc不是真正保存在寄存器中,而是作為進程上下文保存在進程表中的對應表項內)。問題是怎么返回,在父子進程中就分道揚鑣。

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

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

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

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

 UNIX大瓜 回復于:2004-04-27 23:14:44
精辟

 Zalophus 回復于:2004-04-28 03:30:44
問題是,結果顯示是子進程先打印出自己的pid的,是不是子進程先于父進程執(zhí)行了?

 chg.s 回復于:2004-04-28 09:16:31
到底哪個進程執(zhí)行在先,這個和操作系統(tǒng)的調度算法等等很多因素相關。我覺得理解上的困難,關鍵在于為什么會有兩個輸出,而不是誰先誰后。

 zhaojinbo 回復于:2004-04-28 12:35:50
fork之后,操作系統(tǒng)會復制一個與父進程完全相同的子進程,雖說是父子關系,但是在操作系統(tǒng)看來,他們更像兄弟關系,這2個進程共享代碼空間, 但是數據空間是互相獨立的,子進程數據空間中的內容是父進程的完整拷貝,指令指針也完全相同,但只有一點不同,如果fork成功,子進程中fork的返回 值是0,父進程中fork的返回值是子進程的進程號,如果fork不成功,父進程會返回錯誤。
可以這樣想象,2個進程一直同時運行,而且步調一致,在fork之后,他們分別作不同的工作,也就是分岔了。這也是fork為什么叫fork的原因。
至于那一個最先運行,可能與操作系統(tǒng)有關,而且這個問題在實際應用中并不重要,如果需要父子進程協同,可以通過原語的辦法解決。

 luoting 回復于:2004-04-28 15:45:08
清晰!感謝!

 ccf 回復于:2004-04-28 17:06:59
明白了,thanks a lot

 carol1980 回復于:2004-04-28 17:15:21
:D 獲益匪淺

 xhl 回復于:2004-04-28 17:21:44
我在父進程里定義的變量,子進程在創(chuàng)建的時候回自動創(chuàng)建一個副本,那如果我在子進程里,就是pid==0里創(chuàng)建的變量,父進程是不是看不到呢,

就是兩個進程不共享數據段的情況下,父進程在創(chuàng)建子進程的之前的變量自進程都能繼承,但要是父進程在fork后創(chuàng)建的變量,子進程能繼承嗎???

 lenovo 回復于:2004-04-28 17:25:43
它們已經是兩個獨立的進程了,
子進程怎么繼承?

 xhl 回復于:2004-04-28 17:42:06
[quote:315e2dd628="lenovo"]它們已經是兩個獨立的進程了,
子進程怎么繼承?[/quote:315e2dd628]


謝謝,就是說在fork前父進程的東西子進程可以繼承,而在fork后子進程沒有任何和父進程的繼承關系了。在子進程里創(chuàng)建的東西是子進程的,在父進程創(chuàng)建的東西是父進程的??梢酝耆闯蓛蓚€進程。

 lenovo 回復于:2004-04-28 19:46:49
對。

 sniper 回復于:2004-04-28 22:11:15
哦,偶明白了,在程序段里用了fork();之后程序出了分岔,派生出了兩個進程。具體哪個先運行就看該系統(tǒng)的調度算法了。
在這里,我們 可以這么認為,在運行到"pid=fork();"時系統(tǒng)派生出一個跟主程序一模一樣的子進程。該進程的"pid=fork();"一句中pid得到的就 是子進程本身的pid;子進程結束后,父進程的"pid=fork();"中pid得到的就是父進程本身的pid。因此改程序有兩行輸出。

 henngy 回復于:2004-04-29 10:13:32
fock關鍵要控制的是誰先返回!是子進程還是父進程,,用wait控制!

 xangyu 回復于:2004-04-29 11:58:03
真的很不錯!謝謝!!

 adccpeng 回復于:2004-04-30 14:12:13
獲益非淺??!
辛苦!

 playmud 回復于:2004-05-06 14:08:29
有這么麻煩嗎?一個進程打印一句話。

 bierdaci 回復于:2004-05-06 21:14:51
[quote:3f8c8aaf17="xhl"]我在父進程里定義的變量,子進程在創(chuàng)建的時候回自動創(chuàng)建一個副本,那如果我在子進程里,就是pid==0里創(chuàng)建的變量,父進程是不是看不到呢,

就是兩個進程不共享數據段的情況下,父進程在創(chuàng)建子進程的之前的變量自進..........[/quote:3f8c8aaf17]

你說的創(chuàng)建變量是什么意思?變量只能是靜態(tài)的定義,fork是復制進程只要原進程里有的東西都會給復制出來(這里先不管共享不共享,對用戶來說這是透明的你看不到哪里是復制的)。

 hbczjzc 回復于:2004-05-07 13:20:32
編寫進程條時很有用的哦.

 corand 回復于:2004-05-09 13:03:25
fork后子進程跟父進程并行,公用程序段,若用vfork,則父進程被阻塞,等子進程執(zhí)行完之后才會被執(zhí)行

 flw 回復于:2004-05-09 14:09:16
[quote:df58bdf128="sniper"]哦,偶明白了,在程序段里用了fork();之后程序出了分岔,派生出了兩個進程。具體哪個先運行就看該系統(tǒng)的調度算法了。
在這里,我們可以這么認為,在運行到"pid=fork();"時系統(tǒng)派生出一個跟主程序一模一樣的子進程。..........[/quote:df58bdf128]
完全正確。

 sniper 回復于:2004-05-10 10:53:44
補充一下,fork()函數復制了當前進程的PCB,并向父進程返回了派生子進程的pid。而且根據上面“corand”兄的提示,父子進程并 行,打印語句的先后完全看系統(tǒng)的調度算法。打印的內容控制則靠pid變量來控制。因為我們知道fork()向父進程返回了派生子進程的pid,是個正整 數;而派生子進程的pid變量并沒有被改變。這一區(qū)別使得我們看到了他們的不同輸出。

 jjl3 回復于:2004-07-14 11:43:20
我做如下修改

#include <unistd.h> 
#include <sys/types.h> 

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 %d\n",getpid()); 
        else 
                printf("i am the parent process, my process id is %d\n",getpid()); 
}[/code:1:896e04449a] 

結果是 
[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");后,結果是
[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

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

 lenovo 回復于:2004-07-14 13:48:33
看這個:
http://bbs./forum/viewtopic.php?t=244249&highlight=藍色鍵盤

 RedMarquis 回復于:2004-07-14 16:03:04
搭車問一個弱問題:

 if(fork()==0)
    system("cat test.c");
 
這樣是不是會產生2個進程?分別是子進程和cat?

 lenovo 回復于:2004-07-14 16:32:16
man system

 RedMarquis 回復于:2004-07-14 17:10:48
man了下,感覺還是做為個進程,另發(fā)現他的說明里推薦用exec,說什么會產生參數影響,不甚明白,盼樓上的能繼續(xù)解釋一下,謝謝

 默難 回復于:2004-07-14 20:41:12
[quote:1257475361="ccf"]alhost c]# ./a.out
i am the child process, my process id is 4286
i am the parent process, my process id is 4285


我就想不到為什么兩行都打印出來了,在我想來,不管pid是多少,都應該只有一行才對[/quote:1257475361]fork返回值是兩個,一個返回給父進程(子進程的ID)一個返回給子進程(0)

 wujiajia 回復于:2004-07-14 21:30:59
main()
{
int a;
int pid;
printf("AAAAAAAA");//print 一次;
pid=fork();//重這里開始分為兩個
if(pid==0){//在這里定義的變量父進程是不會有的:int b;
printf("ok");}
else if(pid>0){
printf("is ok\n");//if you want print b;error!but you can print a;
}
printf("BBBBBBB");//父子進程都會打印;
}

不知道我的回答是否正確!

 bashfulboy 回復于:2004-07-14 22:10:52
我也來一下:
wujiajia 的理解有些錯誤,
printf("AAAAAAAA");//print 一次;   這里會print 2次
如果你將 printf("AAAAAA") 換成 printf("AAAAAA\n")   那么就是只打印一次了.
主要的區(qū)別是因為有了一個 \n  回車符號
這就跟Printf的緩沖機制有關了,printf某些內容時,操作系統(tǒng)僅僅是把該內容放到了stdout的緩沖隊列里了,并沒有實際的寫到屏幕上
但是,只要看到有 \n 則會立即刷新stdout,因此就馬上能夠打印了.
運行了printf("AAAAAA") 后, AAAAAA 僅僅被放到了緩沖里,再運行到fork時,緩沖里面的 AAAAAA 被子進程繼承了
因此在子進程度stdout緩沖里面就也有了 AAAAAA.
所以,你最終看到的會是 AAAAAA 被printf了2次!!!!
而運行 printf("AAAAAA\n")后, AAAAAA 被立即打印到了屏幕上,之后fork到的子進程里的stdout緩沖里不會有 AAAAAA 內容
因此你看到的結果會是 AAAAAA 被printf了1次!!!!

 ohwww 回復于:2004-07-17 10:19:22
真是佩服各位,很受用

 eagerly1 回復于:2004-07-17 21:51:18
[quote:48b27e4789="ohwww"]真是佩服各位,很受用[/quote:48b27e4789]
是呀

 jjl3 回復于:2004-07-19 15:19:30
:)

 mingjwan 回復于:2004-08-19 10:46:50
根據 chg.s的解釋,請問,子進程在進行fork()操作的時候,是怎么知道自己就子進程,需要返回0,而不是繼續(xù)產生一個子進程呢?

 bjldlee 回復于:2004-09-05 21:26:45
to bashfulboy:


main() 

int a; 
int pid; 
printf("AAAAAAAA");//print 兩次; 
pid=fork();//重這里開始分為兩個,但是子進程也會執(zhí)行這個語句!!!這就產生了悖論!!! 
if(pid==0){//在這里定義的變量父進程是不會有的:int b; 
printf("ok");} 
else if(pid>0){ 
printf("is ok\n");//if you want print b;error!but you can print a; 

printf("BBBBBBB");//父子進程都會打印; 
}

 temin 回復于:2004-10-15 09:20:29
收益,頂

 xhl0902 回復于:2004-10-15 09:51:24
講的夠清楚,夠明了。佩服佩服

 zerglot 回復于:2004-10-15 15:57:59
了解了!haha

 cnufo 回復于:2005-01-10 00:56:01
3x,perfect!

 xujunxp 回復于:2005-01-10 19:57:31
頂,收獲頗多

 superroy 回復于:2005-01-11 14:53:33
[quote:de928d087a="mingjwan"]根據 chg.s的解釋,請問,子進程在進行fork()操作的時候,是怎么知道自己就子進程,需要返回0,而不是繼續(xù)產生一個子進程呢?[/quote:de928d087a]
fork()產生子進程后,父子進程都執(zhí)行fork()之后的語句,即子進程不再執(zhí)行fork()語句。

 郭子耳 回復于:2005-03-05 21:32:10
[quote:8d5e48213c="chg.s"]操作系統(tǒng)創(chuàng)建一個新的進程(子進程),并且在進程表中相應為它建立一個新的表項。新進程和 原有進程的可執(zhí)行程序是同一個程序;上下文和數據,絕大部分就是原進程(父進程)的拷貝,但它們是兩個相互獨立的進程![/quote: 8d5e48213c]

 zlrll 回復于:2005-03-05 22:37:10
其實可以理解為fork就是生成了當前進程的一個副本,與原來進程不同的是原來進程中返回的是>0,副本中返回==0,兩個進程各執(zhí)行一次if(),所以會打印2個了

 hmilyhacker 回復于:2005-03-06 07:49:16
謝謝各位大大,受益匪淺

 lss888 回復于:2005-03-06 20:53:53
[color=red:3819baa262]#include <unistd.h>
#include <sys/types.h>

main ()
{       int i=5;
        pid_t pid;
        pid=fork();
        for(;i>0;i--){
        if (pid < 0)
                printf("error in fork!");
        else if (pid == 0)
                printf("i am the child process, my process id is %d and i=%d\n",getpid(),i);
        else
                printf("i am the parent process, my process id is %d and i=%d\n",getpid(),i);
          }
}[/color:3819baa262]
[color=blue:3819baa262]i am the child process, my process id is 11879 and i=5
i am the child process, my process id is 11879 and i=4
i am the child process, my process id is 11879 and i=3
i am the child process, my process id is 11879 and i=2
i am the child process, my process id is 11879 and i=1
i am the parent process, my process id is 11878 and i=5
i am the parent process, my process id is 11878 and i=4
i am the parent process, my process id is 11878 and i=3
i am the parent process, my process id is 11878 and i=2
i am the parent process, my process id is 11878 and i=1[/color:3819baa262]
我覺得這樣改寫一下就更好理解了

 THEBEST 回復于:2005-03-08 15:30:11
[quote:d26e599e6d="sniper"]哦,偶明白了,在程序段里用了fork();之后程序出了分岔,派生出了兩個進程。具體哪個先運行就看該系統(tǒng)的調度算法了。
在 這里,我們可以這么認為,[color=red:d26e599e6d]在運行到"pid=fork();"時系統(tǒng)派生出一個跟主程序一模一樣的子進程。 該進程的"pid=fork();"一句中pid得到的就是子進程本身的pid;子進程結束后,父進程的"pid=fork();"中pid得到的就是父 進程本身的pid。因此改程序有兩行輸出。
..[/color:d26e599e6d][/quote:d26e599e6d]本來也覺得各位講的挺好的.但你這里說的不太懂,子進程一定先結束?如果系統(tǒng)調度是先執(zhí)行父進程那它執(zhí)行完了不就退出了?然后子進程還要執(zhí)行.

該進程的"pid=fork();"一句中pid得到的就是子進程本身的pid;子進程結束后,父進程的"pid=fork();"中pid得到的就是父進程本身的pid

這是什么意思?怎么還分子進程和父進程的pid = fork()呢?

 THEBEST 回復于:2005-03-08 15:38:51
[quote:5a0826e8f0]因為我們知道fork()向父進程返回了派生子進程的pid,是個正整數;而派生子進程的pid變量并沒有 被改變。這一區(qū)別使得我們看到了他們的不同輸出。[/quote:5a0826e8f0]派生子進程的pid變量并沒有被改變是什么意思?對于子進程來講 pid不就是0嗎?

 albcamus 回復于:2005-03-08 15:56:11
>>派生子進程的pid變量并沒有被改變是什么意思?對于子進程來講pid不就是0嗎?

1,派生子進程的進程,即父進程,其pid不變;
2,對子進程來說,fork返回給它0,但它的pid絕對不會是0;之所以fork返回0給它,是因為它隨時可以調用getpid()來獲取自己的pid;
3,樓上的樓上的你的觀點是對的,fork之后夫子進程除非采用了同步手段,否則不能確定誰先運行,也不能確定誰先結束。認為子進程結束后父進程才從fork返回的,這是不對的,fork不是這樣的,vfork才這樣。

 zlrll 回復于:2005-03-08 20:37:17
[quote:c891178d6b="bashfulboy"]我也來一下:
wujiajia 的理解有些錯誤,
printf("AAAAAAAA");//print 一次;   這里會print 2次
如果你將 printf("AAAAAA") 換成 printf("AAAAAA\n")   那么就是只打印一次了.
主要的區(qū)別是因為有了一個 \n  回車..........[/quote:c891178d6b]

佩服,實在太強了!

 icesummit 回復于:2005-03-08 23:03:55
佩服佩服。碼這么多字已經是很不容易,何況還說的這么清楚呢?

 lchhcllch 回復于:2005-03-09 09:35:51
都成FORK()專家了,貼出fork()實現代碼就完結了.

    本站是提供個人知識管理的網絡存儲空間,所有內容均由用戶發(fā)布,不代表本站觀點。請注意甄別內容中的聯系方式、誘導購買等信息,謹防詐騙。如發(fā)現有害或侵權內容,請點擊一鍵舉報。
    轉藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多

    日韩成人高清免费在线| 国产欧美精品对白性色| 五月天婷亚洲天婷综合网| 国产成人午夜福利片片| 国产精品成人又粗又长又爽| 国产精品免费福利在线| 国产黄色高清内射熟女视频| 亚洲一区精品二人人爽久久| 日韩欧美二区中文字幕| 中文字幕乱码亚洲三区| 国产国产精品精品在线| 东北老熟妇全程露脸被内射| 老司机精品线观看86| 免费在线观看激情小视频| 亚洲欧美视频欧美视频| 正在播放玩弄漂亮少妇高潮 | 91人妻人人澡人人人人精品| 国产精品不卡高清在线观看| 日本91在线观看视频| 国产一区二区精品丝袜| 国产av一区二区三区久久不卡| 91麻豆精品欧美一区| 国产欧美高清精品一区| 日韩免费国产91在线| 91麻豆视频国产一区二区| 香蕉久久夜色精品国产尤物| 亚洲天堂精品一区二区| 中文字幕欧美精品人妻一区| 中文字幕区自拍偷拍区| 久久老熟女一区二区三区福利| 国产精品日韩欧美一区二区 | 好吊日在线视频免费观看| 日韩免费成人福利在线| 日韩成人高清免费在线| 婷婷激情四射在线观看视频| 成年人黄片大全在线观看| 精品偷拍一区二区三区| 国产精品九九九一区二区| 日韩黄色一级片免费收看| 日韩欧美一区二区久久婷婷| 亚洲国产成人爱av在线播放下载|