多叉(Multiple fork):有管子的孩子

Multiple fork() Children with pipes

本文关键字:孩子 Multiple fork 多叉      更新时间:2023-10-16

我试图在c++中创建一个带有fork()的子程序。它应该从argv中获取子节点数并创建这些子节点,每个子节点都创建另一个子节点并通过管道相互通信....

Example ./a.exe 2
**OUTPUT**
P1 exists
P2 created
Write message: Hello
P1 sending message (“Hello”) to P2
P2 received message (“Hello”) from P1

我从argv中获得数字,创建正确的子数目(我认为),用于读写管道的函数,都是OK的。但我有麻烦,使它与多个孩子!

  1. 我的第一个问题是,如果我把超过2在argv,子顺序没有像它应该的那样提升!(创建后显示)
  2. 但我最大的问题是,如果我写有两个字的留言,我只能看空格前的第一个字!!我正在使用scanf.

我的一些代码

//获得,检查ARGV
//打开管

         pid=fork();
         if (pid!=0){

                      waitpid(pid,&child_status,0);
                      printf("nn****Parent Process:ALL CHILD FINISHED!****");
                     }
          else if (pid==0)
          {
                 printf("n P%d Exists n",i); 
                     close (mypipe[READ_END]);
                      write(mypipe[WRITE_END], msg, 256);  /* write pipe*/                   
                       close (mypipe[WRITE_END]);          
                    printf("Write a message: n");
                     scanf("%s",msg);
                       printf("n P%d sending message: '%s' to P%d n",i,msg,i+1); 
         do{
            childpid[i] = fork();
           if (childpid[i] > 0){   

                       /* wait for child to terminate */
                             waitpid(childpid[i],&child_status,0);  
                 }
           else if (childpid[i] == 0)
           {
               /*child process childpid = 0*/
               printf("n P%d Created n",i+1);
               close (mypipe[WRITE_END]);   
                 read(mypipe[READ_END], msg, 256);  /* read pipe */
                 close (mypipe[READ_END]);
                 printf("n P%d received message: '%s' from P%d n",i+1,msg,i);          
                 exit(0);
                 return;
            }
           else{
                   printf("Child Fork failed");
                   }
                      i++;
                   }
                   while (i<x);

                   }
                   else{
                   printf("Fork failed");
                   }    
                          }

我看过其他类似的问题,尝试了很多东西,但没有帮助!!任何帮助都将不胜感激!!谢谢你!

您显示的代码中有多个问题,并且在注释中诊断出有代码缺失。

一个问题是,您关闭了第一个子文件中唯一管道的两端,然后第二次关闭它(但幸运的是,您忽略了这个错误)。更严重的是,任何后续的孩子都只有一个封闭的管道可以使用,这对他们没有任何帮助。

另一个问题是父进程没有关闭管道;在这个程序中,这可能无关紧要,因为您没有尝试读取到EOF,但在大多数程序中,这是重要的。

另一个问题是,在您尝试将未初始化的消息写入管道之前,您不会从标准输入中读取消息。目前还不清楚是否应该将子进程的标准输入连接到管道的读端。即使消息没有那么长,也要向管道写入256字节。

您会遇到多个单词的问题,因为scanf("%s", msg)被设计为读取到第一个空白(空白,换行符,制表符等)。在这种情况下,我可能会使用fgets()来读取信息。

我认为你需要给每个孩子一个新烟斗。您可能应该对每个系统调用进行错误检查,但是如果您有一个简单的错误报告函数,则会更容易,例如:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdarg.h>
#include <errno.h>
static char *arg0 = 0;
static void err_exit(const char *fmt, ...)
{
    int errnum = errno;
    va_list args;
    va_start(args, fmt);
    fprintf(stderr, "%s (%d): ", arg0, (int)getpid());
    vfprintf(stderr, fmt, args);
    va_end(args);
    if (errnum != 0)
        fprintf(stderr, "Error %d: %sn", errnum, strerror(errnum));
    exit(1);
}
int main(int argc, char **argv)
{
    int i=1;
    int x;
    int pid, mypipe[2];
    pid_t childpid[256];
    int child_status;
    char msg[256];
    arg0 = argv[0];
    if (argc != 2 || (x = atoi(argv[1])) <= 0)
        err_exit("Usage: %s num-of-childrenn", argv[0]);
    if (pipe(mypipe) < 0)
        err_exit("pipe errorn");

您需要认真考虑如何组织事物,以便消息从一个进程传递到下一个进程。这只是个开始……错误报告功能可能对您有些用处。