[英]fork() as loop condition statement
我有以下一段代碼,我想解釋這段代碼中 fork() 調用的行為,中斷條件作為命令行參數給出。
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(int argc, char *argv[])
{
int i = 0;
char *ptr;
int x = strtol(argv[1], &ptr, 10);
while (fork())
{
if (i == x)
{
break;
}
printf("PID: %d, PPID: %d, i = %d\n", getpid(), getppid(), i++);
}
return 0;
}
當命令行參數為 1 時,這是 output
PID: 684067, PPID: 14913, i = 0
PID: 684067, PPID: 14913, i = 0
我認為應該發生的是fork()
調用將執行一次,創建一個子進程和父進程,向父進程返回非零進程 ID,向子進程返回零。 零值應被解釋為假,只有父進程會繼續打印一次,然后將 i 的值增加到 1,然后再次重復創建另一個子進程,該子進程將再次不會進入循環,並且這次i = 1
它會跳出循環,那為什么我看到 2 行而不是 1 行? 更高的 i 值的 output 更加令人費解,但可以預見的是打印i*(i+3)/2 行。 誰能解釋我假設中的缺陷?
您看到的重復消息來自 stdio 緩沖,並且printf
默認情況下實際上並不打印 - 它只是將一些內容放入緩沖區中,稍后在刷新緩沖區時打印(當進程退出時發生,如果不是在顯式刷新或緩沖區填滿之前)。
最重要的是,當你 fork 一個孩子時,孩子會得到所有父 state 的副本——包括所有 stdio 緩沖區。 因此,如果 stdio 緩沖區中有任何未刷新的數據,它將被復制並(最終)寫入兩次——一次由父級寫入,一次由子級寫入。
您可以通過放置顯式fflush(stdout);
來避免這種情況。 在printf
之后。
更復雜的是,stdio 還支持一種稱為“行緩沖模式”的東西,在這種模式下,它會在每次寫入換行符時自動刷新 FILE。 在某些系統上,這是默認設置在標准輸出上的,但不是其他系統(它是由實現定義的)。 您可以通過使用setlinebuf(stdout);
在您的主要 function 的開頭。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.