打印 5 个字符串发生得太快,父进程在子进程开始其循环之前就完成了其循环。尝试更多循环,500 Works For Me™。
请注意,父母和孩子do not共享内存。孩子将继承counter = 0
但不分享counter
与其父级。他们都会独立计数。协调流程需要更先进的技术。
其他事宜。
你得到了--end of program--
两次因为子进程没有退出。一旦完成循环,它就会继续运行其余的代码。添加一个exit(0)
给孩子。
如果您想在子进程完成后声明“结束”,请使用wait https://stackoverflow.com/questions/23709888/how-to-use-wait-in-c等待您的子进程完成。
waitpid(pid, NULL, 0);
printf("--end of program--\n");
你可以得到--beginning of program
如果输出到管道或文件,则两次,例如./program | cat
or ./program > output
。由于 I/O 缓冲。
写入磁盘很慢。不是在打印后立即写入所有内容,而是将其写入内存,然后写入磁盘。缓冲共有三种常见类型:无缓冲、行缓冲和块缓冲。哪种类型的缓冲取决于您要写入的内容。
无缓冲就是它所说的,你称之为printf
并已发送。stderr
通常是无缓冲的,因为在错误发生时看到错误很重要。
行缓冲将输出存储在内存中,直到看到换行符,然后发送整行。发送它称为“刷新缓冲区”。stdout
通常是行缓冲的。这是终端在纸上打印一行的回溯。
这可能会导致奇怪的结果。
fprintf(stdout, "First");
fprintf(stderr, "Second");
fprintf(stdout, "Third\n");
Because stdout
是行缓冲区,结果将是SecondFirstThird
.
Unless stdout
or stderr
不会去航站楼。如果它们要访问管道或文件,则它们可能是块缓冲的。这意味着输出将被缓冲,直到看到一定量的数据,然后它将被刷新。
在你的代码中,如果stdout
是行缓冲的printf("--beginning of program\n");
立即被冲洗。但如果stdout
被重定向到一个文件,它是块缓冲的并且不会立即写入。"--beginning of program\n"
仍然在stdout
的缓冲区。当您分叉时,子进程会获取该缓冲区的副本并添加到其中。所以孩子和父母都打印"--beginning of program\n"
.
您可以通过在分叉之前显式刷新标准输出缓冲区来解决此问题fflush https://en.cppreference.com/w/c/io/fflush.
printf("--beginning of program\n");
fflush(stdout);