# Thread: How to get single output from different forks

1. ## 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. 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)
close(p[i][0]);
total += count;
}

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

printf("%d\n", total);

return 0;
}```

3. Originally Posted by john.c
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)
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. Originally Posted by john.c
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)
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. 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