C fork 程序行为解释
C fork program behaviour explanation
我对C 语言和Unix 系统完全陌生。我可能会错误地表述自己。我有一个 C 程序,其中两个进程将一个全局变量递增到 30。我知道并行处理的输出顺序是随机的。 但是当使用 | more 管道,输出始终相同:Child 1-30 -> Parent 1-30。怎么来的?
有人告诉我,当使用 printf 打印变量时,变量内容在打印到屏幕之前被发送到缓冲区。显然您可以使用换行符 (\n) 立即刷新缓冲区。这个信息有关联吗?
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/types.h>
int g_ant = 0;
void writeloop(char *text)
{
long i = 0;
while (g_ant < 30)
{
if (++i % 100000 == 0)
printf("%s: %d\n", text, ++g_ant);
}
}
int main(void)
{
pid_t pid;
pid = fork();
if (pid == 0)
{ /* child */
writeloop("Child");
exit(0);
}
writeloop("Parent"); /* parent */
waitpid(pid, NULL, 0);
return 0;
}
你的信息基本正确
当输出到达终端时,输出是行缓冲的。当输出进入管道时,输出被完全缓冲,因此其中一个进程首先完成其输出。您可以在 writeloop()
中的每次迭代后添加 fflush(stdout)
,或使用 setvbuf()
使其行缓冲,甚至是无缓冲输出。
顺便说一下,全局变量不在子进程和父进程之间共享;他们每个人都有自己的变量副本。
我对C 语言和Unix 系统完全陌生。我可能会错误地表述自己。我有一个 C 程序,其中两个进程将一个全局变量递增到 30。我知道并行处理的输出顺序是随机的。 但是当使用 | more 管道,输出始终相同:Child 1-30 -> Parent 1-30。怎么来的?
有人告诉我,当使用 printf 打印变量时,变量内容在打印到屏幕之前被发送到缓冲区。显然您可以使用换行符 (\n) 立即刷新缓冲区。这个信息有关联吗?
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/types.h>
int g_ant = 0;
void writeloop(char *text)
{
long i = 0;
while (g_ant < 30)
{
if (++i % 100000 == 0)
printf("%s: %d\n", text, ++g_ant);
}
}
int main(void)
{
pid_t pid;
pid = fork();
if (pid == 0)
{ /* child */
writeloop("Child");
exit(0);
}
writeloop("Parent"); /* parent */
waitpid(pid, NULL, 0);
return 0;
}
你的信息基本正确
当输出到达终端时,输出是行缓冲的。当输出进入管道时,输出被完全缓冲,因此其中一个进程首先完成其输出。您可以在 writeloop()
中的每次迭代后添加 fflush(stdout)
,或使用 setvbuf()
使其行缓冲,甚至是无缓冲输出。
顺便说一下,全局变量不在子进程和父进程之间共享;他们每个人都有自己的变量副本。