main()
{
if(!fork())
while(1)
printf("HELLO");
else
while(1)
printf("WORLD");
}
输出:...... HELLO HELLO HELLO ....等, 但执行应该是“RANDOM”,因为fork和parent进程是不同步的 我必须得到你好世界世界你好世界......(按照我预期的随机顺序) 但事实并非如此。 任何人都可以解释一下。
答案 0 :(得分:4)
stdio是缓冲的,因此在填充缓冲区之前,任何进程都不会写入任何内容,然后将整个写入作为单个单元(对于普通文件通常是原子的,但不一定是终端设备,以及它是否是原子的管道是一个复杂的问题)。此外,如果您使用的是单核计算机,则一个进程将持续运行,直到内核认为它已经花费了足够的CPU时间,然后另一个进程将被安排等等。
如果您想让stdio缓冲问题消失,请在setbuf(stdout, 0);
的开头添加main
或使用stderr
(默认情况下无缓冲)。
答案 1 :(得分:1)
好的,首先你没有得到HELLO和WORLDs的随机交错词,因为stdout被缓冲了。
因此,您的父级正在打印HELLO,直到该缓冲区变满,然后整个缓冲区最终会出现在您的屏幕上。孩子一样。
如果要同步此功能,可以使用2个管道在父母和孩子之间进行通信。 例如
-
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
void err(const char *error)
{
perror(error);
exit(1);
}
void run_handler(int readfd,int writefd,const char *message)
{
for(;;) {
char ch;
int i;
if((i = read(readfd,&ch,1)) == 0)
break;
else if(i < 0)
err("read");
//important: fflush the text so it ends up in the output
//and not in an internal FILE* buffer.
if(fputs(message,stdout) == EOF || fflush(stdout) == EOF)
break;
if(write(writefd,&ch,1) != 1)
err("write");
}
}
int main()
{
int pipe1[2];
int pipe2[2];
pid_t pid;
if(pipe(pipe1) != 0)
err("pipe1");
if(pipe(pipe2) != 0)
err("pipe2");
if((pid = fork()) == 0 ) {
//write one char to the parent to get it started
char ch = '.';
if(write(pipe1[1],&ch,1) != 1)
err("write");
//close the pipe ends we don't need
close(pipe1[0]);
close(pipe2[1]);
run_handler(pipe2[0],pipe1[1],"WORLD\n");
}else if(pid > 0) {
//close the pipe ends we don't need
close(pipe1[1]);
close(pipe2[0]);
run_handler(pipe1[0],pipe2[1],"HELLO ");
} else {
err("fork");
}
return 0;
}
答案 2 :(得分:0)
int main()
{
if(!fork())
while(1) {
printf("HELLO");
fflush(stdout);
}
else
while(1) {
printf("WORLD");
fflush(stdout);
}
}
使用它,然后printf的缓冲不会弄乱你的结果。