4

再帰フォークのシステムを使用して800intの配列をマージソートで作成しようとしています。これにより、最下位の子(合計8つ)のそれぞれがそれぞれ100をqsortし、配列をそれぞれの親プロセスに戻してマージします。ソートされ、再び渡されました。

なんらかの理由で、最下位の子の最初のセットが親プロセスへの書き込みを終了した後、関数がハングします。

800の初期配列を受け取る私の再帰フォーク関数...

static void forkSort(int* parentNums, int size)
{
    printf("PPid:%ld Pid:%ld Size:%d\n", (long)getppid(), (long)getpid(), size);
    int childNums[size/2], fd[2], left, right;

    if(size <= 100) //Send sorted array to parent thru pipe
    {
        qsort(parentNums, size, sizeof(int), compare);
        write(fd[1], &parentNums, sizeof(parentNums));
        exit(0);
    }
    if (pipe(fd)==-1){perror("Failed");}

    size /= 2;
    if(!(left = tryFork()) || !(right = tryFork())) //Children
    {
        if(left)    copy(childNums, parentNums, size);
        else        copy(childNums, parentNums + size, size);

        forkSort(childNums, size);
    }
    //Parents
    int first[size], second[size], combined[size*2];
    read(fd[0], first, sizeof(first));
    read(fd[0], second, sizeof(second));

    mergeSort(first, second, combined, size);
    if(size*2 == SIZE) //Finished, write to out.dat
        printArray(combined, SIZE);
    else
        write(fd[0], combined, sizeof(combined));
}
4

1 に答える 1

3

あなたのコードにはいくつか問題があります (これは見ていて楽しかったことを付け加えなければなりません)。

A) クライアント コードで return するだけでなく、exit() する必要があります。そうしないと、特に再帰を行うときに、実行を続行します。

B) パイプの書き込み側をクライアントに渡して、どこに書き込むかをクライアントに知らせる必要があります。これを forkSort() のパラメーターとして追加しました。

C) サイズが <= 100 の場合、 a を実行すると、sizeof(parentNums)これが a に変わります。sizeof(int*)正しい方法は次のとおりsizeof(int)*sizeです。

D) int のマージされたセットを書き戻す場合、最初の部分のみを書き込み、それをパイプの読み取り側に書き込みます。正しい呼び出しは次のとおりwrite(write_fd, combined, sizeof(combined));です。

E) ポイントがわからなかったので、wait(NULL) 呼び出しを削除しました。同期はread()とのwrite()呼び出しによって行われます。

これが私の提案です:

static void forkSort(int* parentNums, int size, int write_fd)
{
  int fd[2];
  printf("PPid:%ld Pid:%ld Size:%d\n", (long)getppid(), (long)getpid(), size);
  int childNums[size/2], left, right;
  if(size <= 100) //Send sorted array to parent thru pipe
    {
      qsort(parentNums, size, sizeof(int), compare);
      write(write_fd, parentNums, size*sizeof(int));
      exit(0);
    }
  if (pipe(fd)==-1){perror("Failed");}

  printf("Creating child processes...\n");
  size /= 2;

  if(!(left = tryFork()) || !(right = tryFork())) //Children
  {
      if(left)    copy(childNums, parentNums, size);
      else        copy(childNums, parentNums + size, size);
      forkSort(childNums, size, fd[1]);
  }

  /* parent */
  int first[size], second[size], combined[size*2];
  read(fd[0], first, sizeof(first));
  read(fd[0], second, sizeof(second));
  printf("\n\nMerge sorting...  Size:%d\n", size*2);
  mergeSort(first, second, combined, size);
  if(size*2 == SIZE) { //Finished, write to out.dat
    printf("\nFinished!!! (%d)\n\n", size * 2);
    printArray(combined, SIZE);
  }
  else {
    write(write_fd, combined, sizeof(combined));
    exit(0);
  }
}
于 2012-12-02T05:12:59.867 に答える