理解C中的Fork
我有一个问题,叉子,我不会丢脸。
#include #include main(){ printf("test 1.\n"); fork(); printf("test 2.\n"); }
输出是:
测试1。
测试2。
测试1。
测试2。
我不应该得到……:
TEST1
TEST2
TEST2
我真的不明白这一点因为fork应该在fork()之后创建子进程; 而不是再次打印teste1。
当您调用printf
,它不会立即打印任何文本。 相反,它等到你打印了很多文本,或者你调用fflush(stdout)
,或程序退出。 (编辑:还有其他东西会导致打印缓冲文本)
当进程分叉时,它会复制未打印文本的缓冲区(包含“test 1. \ n”)。 然后两个进程在退出时打印“test 1. \ n”。
在fork()
fflush(stdout)
之前调用fflush(stdout)
修复了这个问题,确保在进程分支之前实际打印“test 1. \ n”。
试试这个:
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()复制。
使stdout无缓冲
main(){ atexit (exit_message); setvbuf(stdout, NULL, _IONBF, 0); printf("%d test 1\n",getpid()); fork(); printf("%d test 2\n",getpid()); }
摆脱鬼魂
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