main()
{
if(!fork())
while(1)
printf("HELLO");
else
while(1)
printf("WORLD");
}
output :... HELLO HELLO HELLO ....etc, But the execution shoud be "RANDOM" because the fork and parent process is unsynchronized and I MUST GET AS HELLO WORLD WORLD HELLO WORLD ...(something in random order which I was expected) But that is not happened . Ca开发者_如何学Gon any one explain.
stdio is buffered, so neither process will write anything until the buffer is filled, and then will make the whole write as a single unit (which is usually atomic for normal files, but not necessarily for terminal devices, and whether it's atomic for pipes is a complicated matter). Also, if you're on a single-core machine, one process will run continuously until the kernel deems it to have spent enough cpu time, then the other will get scheduled, etc.
If you want to make the stdio buffering issue go away, add setbuf(stdout, 0);
at the beginning of main
or use stderr
(which is unbuffered by default).
Ok, first of all you're not getting a total random intermangled words of HELLO and WORLDs because stdout is buffered.
So your parent is printing HELLO until that buffer gets full, and then that whole buffer ends up on your screen. Same for the child.
If you want to synchronize this, you could use 2 pipes to communicate between your parent and child. e.g.
- parent prints "HELLO",
- child starts reading from the pipe1.
- parent writes a character to the pipe1 to signal that the child should print "WORLD"
- parent starts reading from the pipe2
- child reads from pipe1, prints "WORLD"
- child writes a character to pipe2 to signal that the parent should print "HELLO"
- repeat the above
-
#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;
}
int main()
{
if(!fork())
while(1) {
printf("HELLO");
fflush(stdout);
}
else
while(1) {
printf("WORLD");
fflush(stdout);
}
}
Use this, then printf's buffering won't mess with your results.
精彩评论