爲什麼程序打印4次'do'而不是'do'?Fork()linux問題
代碼:
#include<stdio.h>
#include<unistd.h>
int main()
{
printf(" do ");
if(fork()!=0) printf(" ma ");
if(fork()==0) printf(" to \n ");
else printf("\n");
}
程序打印 做馬 做 做馬到 做
爲什麼程序打印4次'do'而不是'do'?Fork()linux問題
代碼:
#include<stdio.h>
#include<unistd.h>
int main()
{
printf(" do ");
if(fork()!=0) printf(" ma ");
if(fork()==0) printf(" to \n ");
else printf("\n");
}
程序打印 做馬 做 做馬到 做
你在你的 「if」 語句兩次調用fork:
if(fork()!=0) printf(" ma ");
if(fork()==0) printf(" to \n ");
在第一個fork,父A生成一個子B,然後父和子都會調用fork a 第二次。父母會產生孩子C,孩子會產生孩子D.結果是4個過程:A,B,C,D。
A ---- B
| |
C D
由於您的打印件緩衝,直到刷新到標準輸出和每個分叉過程得到這個緩衝區的副本,四「不要」打印(檢查@ilkkachu答案)。
如果你打算有一個「做」,你應該這樣做,而不是:
pid_t pid = fork();
if (pid > 0){
printf(" do ");
printf(" ma ");
} else {
printf(" to \n");
}
基本上兩次存儲叉()的一個變量而不是調用fork返回你的「if」語句。
由於默認情況下標準輸出是行緩衝(或完全緩衝,如果將其重定向到文件或管道)。
第一個printf
未找到換行符,因此它只將字符串do
添加到C庫內部的緩衝區中。在第一個fork
,整個過程,包括該緩衝區,是重複的。然後,其中一個副本增加了ma
到緩衝區中,把兩份都被複制(因爲都過程再次調用fork
,不只是父母或子女)。
最後,無論是printf(" to \n ")
或printf("\n")
被調用,產生換行符,它觸發緩衝區中任何內容的實際寫入。
您可以使用fflush(stdout)
強制C庫在您分叉之前輸出任何緩衝數據,或者使用setbuf(stdout, NULL)
完全禁用緩衝區。
編輯,當然fork() – Klapi