簡體   English   中英

fork() 作為循環條件語句

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM