web-dev-qa-db-ja.com

フォークを使用して計算の部分的な結果を計算するにはどうすればよいですか?

私に与えられた仕事は、数を割るすべての数を見つけて(それをxと呼びましょう)、それが何回それを除算するかを見つけなければならないということです。
I フォークを使用する必要がありますタスクを実行します。
私が思いついたのは、数値がxを除算する回数を計算する関数を作成し、それをforループで実行したところ正常に機能するということです。ただし、これをフォークで「並列化」したいと思います。出来ますか?

私のC関数は次のようになります

int check_dividers(int *x, int i)
{
  int c = 0;

  if (*x % i == 0)
  {
    do
    {
      c++;
      *x = *x / i;
    } while (*x % i == 0);
  }

  return c;
}

新しいプロセスを生成して各計算を実行し、それを出力ファイルに書き込んでみましたが、混乱してしまいます。

 int i = 2;

  while (i < x && x != 0)
  {
    if (x % i == 0)
    {
      pid_t pid;

      if ((pid = fork()) < 0)
      {
        perror("error during fork");
        exit(0);
      }
      else
      {
        if (pid == 0)
        {
          int num_dividers = check_dividers(&x, i);

          fprintf(out, "%d: %d\n", i, num_dividers);
          fflush(out);
        }
      }
    }
    i++;
  }

X = 315の場合の出力

3: 2
5: 1
7: 1
21: 1
9: 1
5: 1
15: 1
9: 1
7: 1
63: 1
7: 1
105: 1
15: 1
9: 1
35: 1
45: 1
21: 1
1
Paralyz3d

何が起こっているのかというと、子プロセスはタスクが完了した後も終了しません。すべてのプロセスは、外部ループの独自のインスタンスを実行します。

フラッシュ後にexit(0)が必要です。

また、子供にはwaitする必要があります。
(1)最後にwhile (wait(NULL) != -1);を使用して、または(2)各プロセスの後にwaitpid(pid, NULL, 0);if ((pid = fork()) < 0) { ... } else { ... }の後に実行できます。
<sys/wait.h>を含める必要があります。

最初のオプションは一時的に多くのゾンビを引き起こしますが、2番目のオプションは並列処理を削除します。

1
Oskar Skog