对多进程输入的理解1

假如在父进程中调用了标准IO,会在用户空间产生一个结构体,其中封装了文件IO返回的文件描述符fd,同时还有针对不同函数的输入输出缓冲区,与之对应的内核空间也有一个文件IO创建的结构体。所以,stdin、stdout和stderr都指向的是用户空间的那个结构体,类型是FILE *。

当调用fork函数创建了子进程后,对于内核空间的那个结构体,子进程不会拷贝,但是对于用户空间的那个结构体,子进程会进行拷贝。即:子进程中的stdin、stdout和stderr的指向是与父进程中的stdin、stdout和stderr不同的(所以子进程的输入缓冲区与父进程的输入缓冲区不在一个位置,同理,他俩的输出缓冲区也不在一个位置),但是内核空间的那个结构体是相同的。

下面一个例子:

   1:  #include <stdio.h>
   2:  #include <unistd.h>
   3:  #include <stdlib.h>
   4:   
   5:   
   6:  int main(void)
   7:  {
   8:      pid_t pid;
   9:      char ch[100] = {"000000000"};
  10:   
  11:      if((pid = fork()) == -1)
  12:      {
  13:          perror("fork error!");
  14:          exit(-1);
  15:      }
  16:      if(pid == 0)
  17:      {
  18:          printf("child ");
  19:          while(1);
  20:      }
  21:      else
  22:      {
  23:          sleep(1);
  24:          printf("parent");
  25:          fflush(stdout);
  26:          printf("\n");
  27:      }
  28:      return 0;
  29:  }

看一下输出结果:

image

结果描述:运行后,过了一秒,屏幕输出parent,然后回车换行,程序退出。尽管父进程调用了函数fflush,程序没有输出child 这句话,这充分说明了,父子进程的输入输出缓冲区是不同的。至于程序为什么会退出?解释:其实这个时候子进程还没有退出,只是变成了一个孤儿进程,由init进程管理,子进程已经脱离bash终端,成为后台进程,或者说bash终端已经失去对子进程的控制。

image

执行命令 ps –ef 可以看到:./a.out的父进程号变成了1,即init进程。执行命令 kill –9 6869 可以将其杀死。

原文地址:https://www.cnblogs.com/pengdonglin137/p/2949734.html