1

The task that has been given to me is that I have to find all numbers that divide a number (let's call it x) and find out how many times does it divide it.
I have to use fork to do the task.
What I have came up with is that I wrote a function which calculates how many times a number divides x and I ran that in a for loop and it works fine. However I want to "parallelize" this with fork. Is it possible?

My C function looks like this

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;
}

I tried spawning a new process to do each calculation and write it to an output file but it just gets messed up.

 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++;
  }

My output if 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
  • What does the part that forks writes and reads look like? – Oskar Skog May 17 at 8:56
  • The thing is that I haven't really used fork. That's what I'm trying to figure out. – Paralyz3d May 17 at 8:57
  • 1
    Try doing that then and post the troublesome code. – Oskar Skog May 17 at 9:00
  • I edited my question – Paralyz3d May 17 at 9:10
  • 1
    Also use a for loop: for (int i=2; i < x && x != 0; i++) {... }. It won't help with the forking, but there is already an answer for that. It will make your code clearer. – ctrl-alt-delor May 17 at 9:36
1

What's happening is that the child processes don't exit after their task has been completed. All processes will be running their own instance of the outer loop.

You need a exit(0) after fflush.

You should also wait for the children.
You can do it (1) in the end with while (wait(NULL) != -1); or (2) after each process with waitpid(pid, NULL, 0); after if ((pid = fork()) < 0) { ... } else { ... }
You'll need to include <sys/wait.h>.

The first option will temporarily cause a lot of zombies but the second removes the parallelism.

| improve this answer | |
  • 1
    There should also be code to wait for the children. Probably not needed for a short lived parent, but it may have highlighted the bug. – ctrl-alt-delor May 17 at 9:37

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.