C 为什么fork函数会把代码中的文件输入搞乱?

C 为什么fork函数会把代码中的文件输入搞乱?,c,fork,stdin,fgets,waitpid,C,Fork,Stdin,Fgets,Waitpid,当我使用fork()创建和终止进程时,我的输出突然出现异常。我希望我的程序读取所有行并终止。但是,当它使用fork时,while循环永远不会终止。 这是我的密码 #include <stdio.h> #include <stdlib.h> #include <sys/wait.h> #include <unistd.h> #include <sys/types.h> #define MAXLINE 1024 int main(voi

当我使用fork()创建和终止进程时,我的输出突然出现异常。我希望我的程序读取所有行并终止。但是,当它使用fork时,while循环永远不会终止。 这是我的密码

#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <unistd.h>
#include <sys/types.h>

#define MAXLINE 1024

int main(void) {
  char buf[MAXLINE];
 
  printf("prompt: \n");

  while (fgets(buf, MAXLINE, stdin) != NULL){
  
   if (fprintf(stdout, "PParent: %s\n", buf) == EOF)
          printf("output err");
    
    pid_t child = fork();

    switch(child){
      case -1: 
        perror("fork");
        exit(EXIT_FAILURE);
        break;
      case 0:
        printf("Child %d: dying\n", getpid());
        exit(0);
    
        break;
      default:
    
    waitpid (child, NULL, 0);
    
    }
  }
  exit(0);
}
但我得到:

prompt: 
Parent: THIS IS LINE 1
Child 14090: dying
Parent: THIS IS LINE 2
Child 14091: dying
Parent: THIS IS LINE 3
Child 14092: dying
Parent: THIS IS LINE 4
Child 14093: dying
Parent: THIS IS LINE 5
Child 14094: dying
Parent: THIS IS LINE 6
Child 14095: dying
Parent: THIS IS LINE 7
Child 14096: dying
Parent: THIS IS LINE 8
Child 14097: dying
Parent: THIS IS LINE 9
Child 14098: dying
Parent: THIS IS LINE 10
Child 14099: dying
Parent: THIS IS LINE 11
Child 14100: dying
Parent: THIS IS LINE 2
Child 14101: dying
Parent: THIS IS LINE 3
Child 14102: dying
Parent: THIS IS LINE 4
Child 14103: dying
Parent: THIS IS LINE 5
Child 14104: dying
Parent: THIS IS LINE 6
Child 14105: dying
Parent: THIS IS LINE 7
Child 14106: dying
Parent: THIS IS LINE 8
Child 14107: dying
Parent: THIS IS LINE 9
Child 14108: dying
Parent: THIS IS LINE 10
Child 14109: dying
Parent: THIS IS LINE 11
Child 14110: dying
Parent: 
Child 14111: dying
Parent: THIS IS LINE 2
Child 14112: dying
Parent: THIS IS LINE 3
...

它将永远消失。如果我不使用fork,我将获得所需的输出。但我的问题是,为什么使用fork会导致输出是这样的?子进程在创建后立即被终止,它甚至不使用STDIN。

使用所有警告和调试信息编译代码:这意味着
gcc-Wall-Wextra-g

仔细阅读当然,然后

然后使用调试器(例如,调试器的
中断
步骤
回溯
打印
运行
命令)。当然,您应该阅读GCC和GDB的文档

根据经验,由于是缓冲的,所以对的每个调用之前都应该有对的调用

对于一个交互式程序,您可以考虑使用而不是<代码> FGES。请参阅(它提供编辑功能)。或者至少使用

我猜您应该编写以下代码:

if (fprintf(stdout, "PParent: %s\n", buf) == EOF)
      printf("output err");
fflush(NULL); ////// this was missing
pid_t child = fork();
当然,同时使用和来理解程序的行为,并理解执行的内容。你可能对我感兴趣

顺便说一句,
fprintf(stdout,
几乎等同于
printf
。因此,如果您的
fprintf(stdout
失败,很可能以下
printf
也失败。请仔细阅读

但我的问题是,为什么使用fork会导致输出是这样的

因为父进程和子进程都在运行。如果处理器在运行(2020年非常常见),则子进程可以在核心0上运行,在核心1上运行父进程,在核心2上运行服务器,在核心3上运行终端仿真器,所有进程都在同一时间运行

此外,Linux在每个内核上有几个进程,使用一些分时机制

详细信息很复杂,请阅读好的。您需要阅读几百页

子进程在创建后立即被终止,甚至不使用STDIN

但它使用(作为父进程)

子进程在创建后立即被终止

您显示的代码没有使用,因此我们不了解孩子是如何被杀死的。当然,您的孩子正在-ing,这会进行一些处理(请参见…),可能相当于
fflush(NULL)
(请参见)。处理确实需要一些时间

考虑研究你的程序的源代码。

两个都在Linux上。Linux也是开源的。还可以考虑下载、学习、编译所有你正在使用的源代码。

你的程序似乎是可行的:FGSH()时结束。遇到EOF。因此,如果您执行类似以下操作:cat file |您的_程序==>此操作将在文件结束时停止。如果以交互方式执行此操作,则CTRL-D将为fgets()生成EOF然后让程序结束。那么,重点是什么?你能分享一个执行的例子吗?你同意每次读一行时都创建一个新的子进程的事实吗?子进程显示“垂死”在每个读取行之后。可能是您的问题是while循环的右括号,因为您可能想在循环之后分叉子循环。因此,请查看while循环的右括号,它位于开关之后(而不是之前)问题是,我希望我的程序的行为就像当我不拨任何孩子。但是,考虑输入10行。我希望程序读取所有10行和退出(打印子模具是没有问题)。但是,我得到一个输出,如打印从线1至10和2至10和空的空间和2至10(永远)。。我不知道是什么系统调用导致了程序中的这种错误行为。我不想修复它,我想知道原因是什么。@b.andarzian:不要评论你自己的问题,这是为了改进它!我在这里看不到答案。我问了程序中不一致的原因。你能只运行一次代码吗?那么你知道我在说什么了吗t、 不,我没有要求做作业。我问了幕后的原因。这不是作业,而是好奇。要逐行运行代码-实际上是一步一步-使用及其
step
命令。要了解程序的行为,请使用
strace
是的,我以前做过,看到我的缓冲区在分叉后变得奇怪yscall。那么你理解你的bug了,是吗?我不明白你所说的“看到我的缓冲区变得怪异”是什么意思。请在你的问题中解释一下(不清楚)。
while (fgets(buf, MAXLINE, stdin) != NULL){
if (fprintf(stdout, "PParent: %s\n", buf) == EOF)
      printf("output err");
fflush(NULL); ////// this was missing
pid_t child = fork();