1. Not finding help here? Sign up for a free 30min tutor trial with Chegg Tutors
    Dismiss Notice
Dismiss Notice
Join Physics Forums Today!
The friendliest, high quality science and math community on the planet! Everyone who loves science is here!

Forking multiple child processes in C++

  1. Oct 25, 2009 #1
    1. The problem statement, all variables and given/known data

    Need to split a file up into four parts, have four child processes assigned to a different part and sum that part, and then send the data to the parent process, which will then sum the four sums.

    2. Relevant equations

    Basic Fork() Knowledge and C++ Knowledge.


    3. The attempt at a solution

    I keep on having the same problem, regardless of how I code the program. The first child process does what it should, but the second, third, and fourth just print 0 for a sum. There must be some fundamental misunderstanding of the material I have, but I can't figure out what that is.

    Code (Text):
    #include <iostream>
    #include <unistd.h>
    #include <fstream>
    #include <sys/wait.h>
    #include <iostream>
    #include <fstream>
    using namespace std;

    int main()
    {
        int i,n=0,total_numbers=0,number, status, split_numbers;
        int previous_number[4];
        int my_number[4];
        int current_number[4] = {1,1,1,1};
        int sum[4] = {0,0,0,0};
        pid_t pid;
        ifstream myfile;
        myfile.open("test.dat");
        while (myfile >> number) {
            total_numbers++;
        }
        split_numbers = total_numbers/4;
        myfile.close();
        pid = fork();

        for (i=0; i<4; i++) {
            if (pid == 0) {
                cout << "Child Process " << i << " " << getpid() << endl;
                myfile.open("test.dat");
                my_number[i] = split_numbers * (i+1);
                previous_number[i] = split_numbers * i + 1;
                while (myfile >> number) {
                    if (my_number[i] >= current_number[i] && previous_number[i] <= current_number[i])                      {
                        sum[i]+=number;
                        current_number[i]++;
                    }
                }
                cout << sum[i] << endl;
                myfile.close();
                exit(0);
            } else {
                waitpid(pid, &status, 0);
                cout << "Parent Process " << getpid() << endl;
                pid = fork();
            }
        }
        return 0;
    }
     
    1. The problem statement, all variables and given/known data



    2. Relevant equations



    3. The attempt at a solution
     
  2. jcsd
  3. Oct 25, 2009 #2

    Hurkyl

    User Avatar
    Staff Emeritus
    Science Advisor
    Gold Member

    I can't figure out what you were trying to do with your while loop. But the reason the sum is zero is because the test
    previous_number <= current_number

    always fails, since the latter is always 1 and the latter is larger than 1. (If split_numbers is positive, anyways)


    About your multi-threading, I have three questions about your setup:
    (1) Was the assignment specifically to use fork()?

    (2) How were you planning on having the children return their partial sum to the parent?

    (3) Did you really intend to spawn children one at a time, rather than spawn all four at once?
     
  4. Oct 25, 2009 #3
    I don't see how previous_number is always 1... When "i" increases, the value of previous_number should increase; I even cout'd the value to make sure. Then it's supposed to go through the file line by line until previous_number <= current_number, and then start summing until my_number >= current_number.

    1.) Yes, the assignment was specifically to use fork.

    2.) We are supposed to "pipe" the sums back to the parent, and then the parent is supposed to add them up.

    3.) Actually, I intended to spawn all the children at the same time. I'd do this, I assume, by removing the "wait" command I have in there. This way it is easier to see if it's working, though.
     
  5. Oct 25, 2009 #4
    Ohh.... I figured it out. I'm supposed to increment current_number every time the loop reads the next line... but I was only doing it if it passed the test, which makes no sense..

    Aha, I'm an idiot. Thanks for nudging me in the right direction!
     
  6. Oct 25, 2009 #5

    Hurkyl

    User Avatar
    Staff Emeritus
    Science Advisor
    Gold Member

    Okay. This is a very sound approach to the problem -- I just wanted to make sure you weren't just making a mistake. (there is a wide variety of skill levels here, and fork() can be surprising to people who are used to things like java.lang.Thread or pthreads)
     
  7. Oct 25, 2009 #6
    So, I have everything correctly implemented, except possibly my processes running concurrently. I got rid of the waitpid function, and it still seems like the order is Process 0, 1, 2, and then 3. Is there something else I need to do to make them run at the same time? Is there an easy way to tell?
     
  8. Oct 25, 2009 #7

    Hurkyl

    User Avatar
    Staff Emeritus
    Science Advisor
    Gold Member

    Fork is a "slow" operation -- your first child probably finished its task before the second child got created.

    If you want to see the concurrency, you could try adding a timed loop to the child task -- make child #n spin-wait for 5-n seconds or something like that, just to see if child 3 really finishes first.
     
  9. Oct 25, 2009 #8
    Alright; thanks a lot for your help!
     
  10. Oct 25, 2009 #9
    One last quick question: When I run my program in Linux, it doesn't quit automatically; I have to Ctrl-C out of the program. This is problematic, because I want to use "time ./a.out" to see how long my program runs, and I can only see that result after I push Ctrl-C, thereby giving me an incorrect result.
     
Know someone interested in this topic? Share this thread via Reddit, Google+, Twitter, or Facebook




Similar Discussions: Forking multiple child processes in C++
Loading...