2014-01-25 19 views
6

我有一個問題叉,我不undertsand。瞭解叉C在C

#include <stdio.h> 
    #include <string.h> 

    main(){ 
     printf("test 1.\n"); 

     fork(); 

     printf("test 2.\n"); 
    } 

輸出爲:

測試1.
測試2.
測試1.
測試2.

我不應該越來越...:
TEST1
test2
test2

我真的不明白這一點,因爲fork應該在fork()之後創建子進程。而不是再次打印teste1。

+5

會發生什麼的;''之前叉();'? – immibis

+1

你錯過了'unistd.h'頭文件。 – Mat

+0

@KarolyHorvath +1輸出是'test1 \ ntest2 \ ntest2' – atupal

回答

5

當您致電printf時,它不會立即打印任何文本。相反,它會一直等到你打印了很多文字,或者你打電話給fflush(stdout),或者程序退出。 (編輯:還有其他一些會導致緩衝文本被打印的東西)

當進程分叉時,它複製未打印文本的緩衝區(其中包含「test 1. \ n」)。兩個進程在退出時會打印「test 1. \ n」。

調用fflush(stdout)之前fork()修復此問題,確保「test 1. \ n」實際上打印在進程分叉之前。

1

試試這個:

void exit_message (void) 
{ 
    // use write to have an unbuffered output 
    char m[100]; 
    sprintf (m, "%d exit\n", getpid()); 
    write (1, m, strlen(m)); 
} 

main(){ 
    atexit (exit_message); 

    printf("%d test 1\n",getpid()); 

    fork(); 

    printf("%d test 2\n",getpid()); 
    } 

輸出將是這樣的:

14866 exit // <- parent process flushes its output at exit 
14866 test 1 // <- parent process: 1st printf 
14866 test 2 // <- parent process: 2nd printf 
14867 exit // <- forked process flushes its output at exit 
14866 test 1 // <- forked process: unflushed parent process output buffer 
14867 test 2 // <- forked process: 2nd printf 

我們可以看到用兩岔過程中所做的唯一的printf是最後一個,符合市場預期。

上一行是stdout輸出緩衝區的重影,它在刷新之前被fork()重複。

製作標準輸出緩衝

main(){ 
    atexit (exit_message); 
    setvbuf(stdout, NULL, _IONBF, 0); 
    printf("%d test 1\n",getpid()); 

    fork(); 

    printf("%d test 2\n",getpid()); 
} 

如果加上`fflush(標準輸出)擺脫了鬼

14866 test 1 // <- parent process: 1st printf 
14866 test 2 // <- parent process: 2nd printf 
14866 exit // <- parent process exits 
14867 test 2 // <- forked process: 2nd printf 
14867 exit // <- forked process exits 
+0

在第一個例子中調用'setvbuf()'應該通過'_IOFBF'(「完全緩衝」)而不是'_IONBF'。 – alk

+0

@alk啊好吧,我明白了。我忘記了刪除該行。發佈更新,謝謝。 –