繁体   English   中英

分叉执行顺序

[英]fork order of execution

main()
{
if(!fork())
 while(1)
  printf("HELLO");
else
 while(1)
  printf("WORLD");

}

输出:... HELLO HELLO HELLO .... etc,但是执行应该是“ RANDOM”,因为fork和父进程是不同步的,因此我必须以HELLO WORLD WORLD HELLO WORLD的身份获取...(我按某种随机顺序是预期的),但是那没有发生。 谁能解释。

stdio是经过缓冲的,因此在缓冲区被填满之前,没有一个进程会写任何东西,然后将整个写成一个单元(通常对于普通文件来说是原子的,但对于终端设备来说不一定,而对于管道来说是否是原子的)一个复杂的问题)。 另外,如果您使用的是单核计算机,则一个进程将连续运行,直到内核认为它已经花费了足够的cpu时间,然后另一个进程将被调度,以此类推。

如果要消除stdio缓冲问题,请添加setbuf(stdout, 0); main的开头或使用stderr (默认情况下为无缓冲)。

好的,首先,因为stdout已缓冲,所以您不会得到HELLO和WORLDs的总随机交错字。

因此,您的父母正在打印HELLO,直到缓冲区已满,然后整个缓冲区最终显示在屏幕上。 孩子也一样。

如果要进行同步,则可以使用2个管道在父级和子级之间进行通信。 例如

  • 父打印“ HELLO”,
  • 孩子开始从pipe1读取。
  • 父级将一个字符写入pipe1以表示子级应打印“ WORLD”
  • 父母开始从pipe2读取
  • 孩子从pipe1读取,打印“ WORLD”
  • 子代将一个字符写入pipe2以表示父代应打印“ HELLO”
  • 重复以上

-

#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);
    }
}

使用它,然后printf的缓冲不会弄乱您的结果。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM