Thread: How to get single output from different forks

  1. #1
    Registered User
    Join Date
    Nov 2018
    Posts
    13

    Question How to get single output from different forks

    Hello, I am trying to write a program with multiple forks, but trying to figure out how to show as single output from all the Childs. In this case, just show total number of primes calculated from each child.

    So far, I have created the logic and same child runs in for loop and gives individual output.

    I am trying with pipes, but stuck on how to use them here. Also, in below I am doing only with one fork(), but I would like to extend this to perform with multiple forks, so multiple Childs can run. Thanks!

    Code:
    #include <sys/types.h>
    #include <unistd.h>
    #include <sys/wait.h>
    #include <stdio.h>
    #include <math.h>
    
    
    #define N 100
    #define K 5
    typedef int bool;
    #define FALSE 0
    #define TRUE 1
    
    
    bool chkPrime(long num) {
     //<Check prime number logic>
    return TRUE;
    }
    
    
    int  main() {
    
    
     pid_t pid;
     int status;
     pid = fork();
    
     for ( int i=0; i<K; i++) {
     
      if ( pid == 0 ) {
    
    
        //Inside child
    
    
        int nextCand = (N/K) * i;
        int ulimit = (N/K) * (i+1);
        int pCount = 0;
    
    
        printf("nextCand: %d\n", nextCand);
        printf("ulimit: %d\n", ulimit);
    
    
        while(nextCand < ulimit) {
    
    
            if(chkPrime(nextCand)) {
                //printf("Child isPrime: %d \n", nextCand);
                pCount++;
            }
    
    
            else {
                //printf("Child not prime: %d \n", nextCand);
            }
    
    
            nextCand +=1;
        }
    
            printf("End of Child %d, primes found: %d\n", i, pCount);
    
      }
    
    
     }
    
    }

  2. #2
    Registered User
    Join Date
    Dec 2017
    Posts
    1,641
    I guess you could do something like this, but it's more of a task for threads.
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <stdbool.h>
    #include <math.h>
    #include <unistd.h>
    #include <sys/types.h>
    #include <sys/wait.h>
     
    #define N 1000000
    #define K 4
     
    void die(const char *msg) {
        perror(msg);
        exit(EXIT_FAILURE);
    }
     
    bool chkPrime(long num) {
        if (num <= 2) return num == 2;
        if (num % 2 == 0) return false;
        int sqroot = sqrt(num);
        for (long i = 3; i <= sqroot; i += 2)
            if (num % i == 0)
                return false;
        return true;
    }
     
    int main() {
        const int GroupSize = (int)ceil((double)N / K);
        int total = 0;
        int p[K][2];
     
        for (int i = 0; i < K; i++) {
            if (pipe(p[i]) == -1) die("pipe");
            pid_t pid = fork();
            if (pid == 0) {
                close(p[i][0]);
                int n    = GroupSize *  i;
                int high = GroupSize * (i+1);
                if (high > N) high = N;
                int count = n <= 2 && high >= 2;
                if (n % 2 == 0) ++n;
                for ( ; n < high; n += 2)
                    if (chkPrime(n))
                        count++;
                if (write(p[i][1], (void*)&count, sizeof count) != sizeof count)
                    die("write");
                exit(0); // closes pipe
            }
            else
                close(p[i][1]);
        }
     
        for (int i = 0; i < K; i++) {
            int count;
            if (read(p[i][0], (void*)&count, sizeof count) != sizeof count)
                die("read");
            close(p[i][0]);
            total += count;
        }
     
        for (int i = 0; i < K; i++)
            wait(NULL);
       
        printf("%d\n", total);
     
        return 0;
    }
    A little inaccuracy saves tons of explanation. - H.H. Munro

  3. #3
    Registered User
    Join Date
    Nov 2018
    Posts
    13

    Thumbs up

    Quote Originally Posted by john.c View Post
    I guess you could do something like this, but it's more of a task for threads.
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <stdbool.h>
    #include <math.h>
    #include <unistd.h>
    #include <sys/types.h>
    #include <sys/wait.h>
     
    #define N 1000000
    #define K 4
     
    void die(const char *msg) {
        perror(msg);
        exit(EXIT_FAILURE);
    }
     
    bool chkPrime(long num) {
        if (num <= 2) return num == 2;
        if (num % 2 == 0) return false;
        int sqroot = sqrt(num);
        for (long i = 3; i <= sqroot; i += 2)
            if (num % i == 0)
                return false;
        return true;
    }
     
    int main() {
        const int GroupSize = (int)ceil((double)N / K);
        int total = 0;
        int p[K][2];
     
        for (int i = 0; i < K; i++) {
            if (pipe(p[i]) == -1) die("pipe");
            pid_t pid = fork();
            if (pid == 0) {
                close(p[i][0]);
                int n    = GroupSize *  i;
                int high = GroupSize * (i+1);
                if (high > N) high = N;
                int count = n <= 2 && high >= 2;
                if (n % 2 == 0) ++n;
                for ( ; n < high; n += 2)
                    if (chkPrime(n))
                        count++;
                if (write(p[i][1], (void*)&count, sizeof count) != sizeof count)
                    die("write");
                exit(0); // closes pipe
            }
            else
                close(p[i][1]);
        }
     
        for (int i = 0; i < K; i++) {
            int count;
            if (read(p[i][0], (void*)&count, sizeof count) != sizeof count)
                die("read");
            close(p[i][0]);
            total += count;
        }
     
        for (int i = 0; i < K; i++)
            wait(NULL);
       
        printf("%d\n", total);
     
        return 0;
    }
    Thanks much! I have update mine also to put fork() inside for loop and getting individual outputs. But stuck with pipes to send the outputs, this is because, I have never worked with pipes before. If you don't mind, could you please help in explaining the pipes that you have used in your code? So I will use the concept in my code and in future?

    Thanks.

  4. #4
    Registered User
    Join Date
    Nov 2018
    Posts
    13
    Quote Originally Posted by john.c View Post
    I guess you could do something like this, but it's more of a task for threads.
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <stdbool.h>
    #include <math.h>
    #include <unistd.h>
    #include <sys/types.h>
    #include <sys/wait.h>
     
    #define N 1000000
    #define K 4
     
    void die(const char *msg) {
        perror(msg);
        exit(EXIT_FAILURE);
    }
     
    bool chkPrime(long num) {
        if (num <= 2) return num == 2;
        if (num % 2 == 0) return false;
        int sqroot = sqrt(num);
        for (long i = 3; i <= sqroot; i += 2)
            if (num % i == 0)
                return false;
        return true;
    }
     
    int main() {
        const int GroupSize = (int)ceil((double)N / K);
        int total = 0;
        int p[K][2];
     
        for (int i = 0; i < K; i++) {
            if (pipe(p[i]) == -1) die("pipe");
            pid_t pid = fork();
            if (pid == 0) {
                close(p[i][0]);
                int n    = GroupSize *  i;
                int high = GroupSize * (i+1);
                if (high > N) high = N;
                int count = n <= 2 && high >= 2;
                if (n % 2 == 0) ++n;
                for ( ; n < high; n += 2)
                    if (chkPrime(n))
                        count++;
                if (write(p[i][1], (void*)&count, sizeof count) != sizeof count)
                    die("write");
                exit(0); // closes pipe
            }
            else
                close(p[i][1]);
        }
     
        for (int i = 0; i < K; i++) {
            int count;
            if (read(p[i][0], (void*)&count, sizeof count) != sizeof count)
                die("read");
            close(p[i][0]);
            total += count;
        }
     
        for (int i = 0; i < K; i++)
            wait(NULL);
       
        printf("%d\n", total);
     
        return 0;
    }
    why do we need last for loop at that place? Isn't it, the forks are completed by the time?

    Code:
    for (int i = 0; i < K; i++)
            wait(NULL);
    

  5. #5
    Registered User
    Join Date
    Dec 2017
    Posts
    1,641
    If by "the forks are completed" you mean the the processes that the forks created have terminated, then that is probably true at that point since we pretty much waited for their completion when we read from their respective pipes. And in either case we already have all the data from them that we want.

    However it is considered good manners to clean up after yourself by "wait"ing on the processes. Furthermore, although we are not availing ourselves of the opportunity, we could also at that point check the return status of the processes and report any failures.

    See Zombie process - Wikipedia
    A little inaccuracy saves tons of explanation. - H.H. Munro

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 1
    Last Post: 03-06-2017, 01:08 AM
  2. multiple condition for single variable in single line
    By merafiq in forum C Programming
    Replies: 2
    Last Post: 03-13-2016, 05:26 PM
  3. Signals and forks
    By Lina_inverse in forum C Programming
    Replies: 1
    Last Post: 12-09-2012, 05:58 PM
  4. many forks
    By quo in forum C++ Programming
    Replies: 1
    Last Post: 06-07-2012, 02:34 PM
  5. Visual Studio - "Single-EXE" output
    By Petike in forum C++ Programming
    Replies: 4
    Last Post: 02-07-2009, 05:54 AM

Tags for this Thread