开发者

fork order of execution

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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜