在C语言中,2个子代向管道写入数据,父代从管道读取数据

在C语言中,2个子代向管道写入数据,父代从管道读取数据,c,fork,pipe,C,Fork,Pipe,我找了又找,都没找到,所以我终于来寻求帮助了。 我的任务包括(在RedhatLinux上运行的C中)创建两个子进程,每个子进程都将任意迭代次数的字符写入管道。此管道与创建它们的父进程共享。父级从管道中读取,而子级仍有要写入的字符。一旦子管道退出且管道为空,则父管道(干管)可以终止 下面是我编写的代码逻辑的一个快速而肮脏的示例 main() { //create pipe fork(); //childA //writes to pipe fo

我找了又找,都没找到,所以我终于来寻求帮助了。 我的任务包括(在RedhatLinux上运行的C中)创建两个子进程,每个子进程都将任意迭代次数的字符写入管道。此管道与创建它们的父进程共享。父级从管道中读取,而子级仍有要写入的字符。一旦子管道退出且管道为空,则父管道(干管)可以终止

下面是我编写的代码逻辑的一个快速而肮脏的示例

main()
{
      //create pipe

      fork(); //childA
      //writes to pipe 

      fork(); //childB
      //writes to pipe

      //parent reading
      while(condition) {
          //read from pipe + print chars to terminal
      }
}
现在,我的问题是关于while循环的条件。
当孩子们因为管道堵塞而无法写作时,我需要阅读,但我不知道什么样的条件允许我这样做。任何帮助都是绝对令人惊奇的

阅读时是否要求管道装满?或者,这仅仅是一项要求,即即使其中一个管道已满,您也要让两个孩子都继续阅读,这样孩子就无法写作了

我不知道有什么标准的方法可以在管道充满的情况下达到高度。您可以尝试使用
FIONREAD
ioctl来确定管道上要读取的数据量,并将其与
pipe\u BUF
进行比较,但如果管道中的数据量小于
pipe\u BUF
,但孩子正在进行写入操作,从而将其置于
pipe\u BUF
之上,则可能无法正常工作;那通电话可能会阻塞,而不会堵塞管道。我不会依靠这种技术工作

保持读取两个文件描述符的常用方法是使用系统调用,而不管哪一个已经准备好。这允许您等待一个或另一个文件描述符具有可用数据。这意味着父进程不会阻止尝试从一个子进程读取数据,而另一个子进程由于缓冲区已满而被阻止

编辑:重新阅读您的问题后,听起来似乎实际上只有一个管道,两个孩子都在给它写信。对吗?再一次,问题来了,你是否需要等待,直到孩子们阻止。如果父级只是从管道中读取,它将阻塞,直到其中一个子级写入管道;你不需要做任何特别的事情

如果你的任务要求你等到水管真的满了,我想看看确切的措辞,因为我不知道你为什么要这么做

编辑2:回答评论中的问题:

  • 父进程的代码是否需要遵循程序中两个子进程的代码

    不,对于父进程或子进程的代码顺序没有要求。为了区分父级运行的代码和子级运行的代码,请检查
    fork()
    的返回值。如果返回值为0,则您处于子进程中。如果不是,则表示您在家长中;如果返回值为-1,则存在错误,如果为正,则为子进程的PID

    因此,您可以编写如下代码:

    int pid = fork();
    if (pid) { 
        // in the parent, check if pid is -1 for errors
    } else {
        // in the child
    }
    
    或:

  • 我怎么能一直从管子里读到两个孩子死了,管子空了

    继续阅读,直到
    read
    返回0<管道读取端的代码>读取将不会返回0,直到所有进程关闭管道的写入端,并且所有数据都已从管道中读取。如果某个对象仍处于打开状态,但管道中没有数据,
    read
    将阻塞,直到数据写入管道

    一个问题是,在尝试
    读取之前,请记住关闭父进程中管道的写入端;否则,当父级尝试在子级完成后执行
    读取
    时,它将阻止等待它关闭自己的管道


  • 你应该经常读到:这是摆脱“满管”状态的唯一方法。一旦最后一个子项关闭管道,读取将返回-1。@wildplasser
    read
    在文件结束时返回0,出错时返回-1;因此,当最后一个子级关闭管道并且没有数据可读取时,它将返回0
    fread
    返回的值小于您请求的对象数(或0),您需要使用
    feof
    FEROR
    来确定是否有文件结尾或错误。实际上,只有一个管道,两个子管道都在写入,而父管道都在读取。好吧,赋值的要求是,父级每次读取管道中的100个字符,然后将这些字符打印到终端。这样做直到每个子级都完成了它的每个迭代(childA=900次迭代,childB=260次迭代)。我想我不必等到孩子们堵住了,但每次读的时候我确实需要从管道里读100个字符。父进程的代码是否需要遵循程序中两个子进程的代码?2.我怎样才能一直从管道中阅读,直到两个孩子终止,管道变空为止?@user1807614我已经在回答中回答了你的问题
    int pid = fork();
    if (pid == 0) {
        // in the child, do whatever you need to do and...
        exit(0);
    }
    
    // in the parent; since the child calls exit() above, control will never
    // reach here in the child.  Or you could do an execl() in the child, which 
    // replaces the current program with another one, so again, control will 
    // never reach here within the child process.