我正在创建几个子进程并使用消息队列传递数据 . 我已经删除了我的代码的大部分细节,因为它有点太大了,无法在线发布作业,我已经缩小了与我如何创建和处理子进程有关的错误 .

该计划的基本工作是:

  • 从标准输入读取

  • fork一个子进程(类型1)来处理数据

  • 通过消息队列将该数据发送到类型2的X个子进程数

  • 他们填充数据并通过消息队列传递给print_queue函数

  • type2进程等到它们的消息队列为空(由print_queue读取),然后才会退出exit(0)

我删除的程序中的所有东西都可以运行并经过测试 . 消息传递正在工作,从stdin读取和计算的东西正在工作 . 当我打印数据时出现问题 . 结果取决于数据集的大小以及我如何获取数据 . 如果我打印到终端,一切都很好 . 如果我将输出重定向到文件,我会得到以下结果(请记住我在main的顶部打印“启动程序”):

** valid data
.
. x100k more lines of valid data
.
.
** valid data
** vali Starting Program
Starting Program

请注意,看起来程序最后重启了两次 . 对于较小的数据集,该程序运行良好,甚至在打印到屏幕时也可以运行非常大的数据集 . 另一个更奇怪的错误是当我注释掉“启动程序”printf时 . 由于某种原因,总是会导致程序出现段错误 .

这是源代码的精简版本:

/*
      fork a process, child process type 1
    */
    void Process1(){

      switch(fork()){
        case 0:

         // Read some stuff from stdin

         // Pass data to other child processes through msgsnd

        //  wait until message queue is empty

         // close message queue, to tell child processes (type 2)
       //   that there is no more data

         break;
        case -1:
          perror("error fork\n");
          break;
        default:
          break;
      }

    }


    /*
      fork a process of type 2
    */
    void process2( ){

      switch(fork()){
        case 0:

         //   Create a child process type-2

         //   Do stuff with this data

        //    send data back to print_queues function 
         //   to do stuff with and display the results

        //    exit to get out and avoid going back to main

          exit(0);

        case -1:
          perror("error fork\n");
          break;

        default:
          break;
      }
    }


    void print_queues(){

       //   This just prints data sent to it from process2 message queues
    }

    int main(int argc, char *argv[]){

     // get a value num from argv, this is the 
    // number of instances of process2 that we will create

      while ((c = getopt (argc, argv, "n:")) != -1)
      {
        switch (c)
        {
        case 'n':
          if(atoi(optarg) < 0 || atoi(optarg) > 50){
            printf("invalid No \n");
            num = 1;
          }
          else{
            num = atoi(optarg);
          }
          // create memory for key and queue arrays
          Keys = malloc(sizeof(key_t)*num);
          queues = malloc(sizeof(int)*num);
          fflush(stdout);
          break;
        default:
          break;
        }
      }

      printf("Starting program\n");

      // create num version of child2
      for(i = 0; i < num; i++){
        process2();
      }

      // create process1
      process1(); 

     // wait for process 1 to finish
      wait(NULL);

    // print the output from the message queues
      print_queues();

    // wait for num versions of process2 to finish
      for(i = 0; i < num; i++){
        wait(NULL);
      }

      return 0;
    }