0

I'm trying to create a parent process with multiple child processes using fork() in C++. I tried using the code from this question to create a simple program that would have each process count upwards; the parent would print "I am process 0", the first child "I am process 1", and so on.

#include <unistd.h>
#include <stdio.h>
#include <fstream>
#include <sys/wait.h>
using namespace std;

const int PROCESSES = 5;
void Printer(int psno);
int iAmProcess = 0;

int main()
{

    int pids[PROCESSES];

    Printer(iAmProcess);

    for (int j = 0; j < PROCESSES; j++)
    {
        if (pids[j] = fork() < 0)
        {
            perror("Error in forking.\n");
            exit(EXIT_FAILURE);
        }
        else if (pids[j] == 0)
        {
            Printer(iAmProcess);
            exit(0);
        }
    }

    int status;
    int pid;
    int n = PROCESSES;
    while (n > 0)
    {
        pid= wait(&status);
        --n;
    }
    return 0;
}

void Printer(int psno)
{
    printf("I am process %d\n", psno);
}

Instead of the expected output:

I am process 0
I am process 1
I am process 2
I am process 3
I am process 4
I am process 5

I get:

I am process 0
I am process 0
I am process 0
I am process 0

And then the program terminates. What am I doing wrong?

ckess
  • 23
  • 1
  • 2
  • where did you update IamProcess to != 0, i dont see it – pm100 Oct 09 '18 at 23:59
  • I added a line that said "iAmProcess = j+1;" to the for loop. However, it's now just returning "I am process 1" 4 times instead of the intended output. – ckess Oct 10 '18 at 03:17

1 Answers1

0

What am I doing wrong?

One thing that you're doing wrong is on this line:

    if (pids[j] = fork() < 0)

Due to the order-of-operations/precedence rules in C++, that line is being interpreted by the compiler as:

    if (pids[j] = (fork() < 0))

... which is to say, pids[j] is being set to true (aka 1) if fork() returns a negative value, or to false (aka 0) otherwise. That's probably not what you intended. What you want to write instead is:

    if ((pids[j] = fork()) < 0)

... so that pids[j] will be set to the return value of fork(), and then that value will be tested to see if it less than zero. (I always use explicit parentheses in this sort of situation, specifically because I can never quite remember the operator-precedence rules, and placing explicit parentheses means I [and the code's future readers] don't have to remember them)

With that change (and the addition of the iAmProcess = j+1; line that you mentioned in your comment, to the top of of the for-loop -- feel free to edit your post to update your code snippet, btw), I get this output from your program:

$ ./a.out
I am process 0
I am process 2
I am process 1
I am process 3
I am process 4
I am process 5

... which isn't exactly what you expected (the output isn't quite in order), but that's because the child processes you spawn all run asynchronously to each other and are not required to execute in any particular order relative to each other.

Jeremy Friesner
  • 70,199
  • 15
  • 131
  • 234
  • Thanks, that does it! It doesn't matter if they execute in order (though when I run it, they consistently do); I was just trying to make a program with multiple concurrent processes and was using this to try and figure out how to do it. – ckess Oct 11 '18 at 01:42