fork()与pid
寫在前面:最近學到Linux的進程間通信,發現以前學的進程有點忘了,就找了一些博客來看,這篇博客講的挺簡單易懂的,就搬運來當筆記了,原文也是轉載的找不到出處,有知道的可以告訴我,我再加上。
fork調用的一個奇妙之處就是它僅僅被調用一次,卻能夠返回兩次,它可能有三種不同的返回值:
??? 1)在父進程中,fork返回新創建子進程的進程ID;
??? 2)在子進程中,fork返回0;
??? 3)如果出現錯誤,fork返回一個負值;
創建新進程成功后,系統中出現兩個基本完全相同的進程,這兩個進程執行沒有固定的先后順序,哪個進程先執行要看系統的進程調度策略。此時,兩個進程都從fork開始往下執行,只是pid不同。
????有人可能疑惑為什么不是從#include處開始復制代碼的?
看下圖:
????? 上圖表示一個含有fork的程序,而fork語句可以看成將程序切為A、B兩個部分。然后整個程序會如下運行:
????? step1、設由shell直接執行程序,生成了進程P。P執行完Part. A的所有代碼。
????? step2、當執行到pid = fork();時,P啟動一個進程Q,Q是P的子進程,和P是同一個程序的進程。Q繼承P的所有變量、環境變量、程序計數器的當前值。
????? step3、在P進程中,fork()將Q的PID返回給變量pid,并繼續執行Part. B的代碼。
????? step4、在進程Q中,將0賦給pid,并繼續執行Part. B的代碼。
????? 這里有三個點非常關鍵:
??????1、P執行了所有程序,而Q只執行了Part. B,即fork()后面的程序。(這是因為Q繼承了P的PC-程序計數器)
????? 2、Q繼承了fork()語句執行時當前的環境,而不是程序的初始環境。
????? 3、P中fork()語句啟動子進程Q,并將Q的PID返回,而Q中的fork()語句不啟動新進程,僅將0返回。
#include <unistd.h>?
#include <sys/types.h>
main ()?
{?
???????? pid_t pid;?
???????? printf("hello!\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());
???????? printf("bye!\n");
}?
這里可以看出parent process執行了printf("hello!\n");? 而child process 沒有執行printf("hello!\n");?
有一個讓人很迷惑的例子:
#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!\n");?
???????? 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());
}?
此時打印輸出了兩個fork!這不免讓人以為是child process從#include處開始執行,所以也執行了printf("fork!");?語句。
其實不然,出現這種問題的原因在于:
這就跟Printf的緩沖機制有關了,printf某些內容時,操作系統僅僅是把該內容放到了stdout的緩沖隊列里了,并沒有實際的寫到屏幕上 。但是,只要看到有\n, 則會立即刷新stdout,因此就馬上能夠打印了.
mian函數(parent process)運行了printf("fork!") 后, "fork!"僅僅被放到了緩沖里,再運行到fork時,緩沖里面的 AAAAAA 被子進程(child process)繼承了,因此在子進程度stdout緩沖里面就也有了"fork!"。所以,你最終看到的會是?"fork!"?被printf了2次!!!!?
而mian函數(parent process)運行 printf("fork!\n")后,"fork!"?被立即打印到了屏幕上,之后fork到的子進程(child process)里的stdout緩沖里不會有"fork!"內容 因此你看到的結果會是"fork!"?被printf了1次!!!!?
總結
以上是生活随笔為你收集整理的fork()与pid的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: main函数的参数详解,它们是何时何处传
- 下一篇: 检测子进程的结束返回状态,status的