3

How can I display the number of processes created?
(without using a formula)

for (i=0; i<3; i++)
fork();
count = count + 1;
printf("%d",count);
hbaderts
  • 14,136
  • 4
  • 41
  • 48
Alice
  • 79
  • 1
  • 6
  • What are you asking? Are you trying to figure out how to count the number of processes? Or do you want code that allows the original process to determine how many descendants it currently has? Or do you want the original parent to collect reports from all of its children giving the number of children they have spawned? What do you want to do? – William Pursell Mar 24 '15 at 22:42
  • If you just want to know how many processes are created, have each process output one line of text. Count the lines of output. Be careful that you have flushed the output streams before you fork, or some output will be duplicated. – William Pursell Mar 24 '15 at 22:49
  • Like William said, don't understand your question. That code controls the number of fork calls in the loop. So it already knows the number of processes that are created. So what exactly are you asking?? – kaylum Mar 24 '15 at 22:53
  • Yes, I'm trying to figure out how to count the number of processes and how to print it only a single time. – Alice Mar 24 '15 at 23:03
  • I need an algorithm to count total of processes created and to display it only once. – Alice Mar 24 '15 at 23:06
  • Like I said, the code already knows the number of fork calls. For example, if all the fork calls succeed then the count is already in the variable "i". So printing out "i" will give you the count. A full solution would check the return value of fork in case any fail. If return value is >0 then increment count. – kaylum Mar 24 '15 at 23:09
  • But If I write something after the for loop this is printed too many times. How can I print something only once? I mean,outside of all the processes. – Alice Mar 24 '15 at 23:12
  • You need to understand the return values for fork. In particular the parent and child processes see a different fork return value. The child will always see 0. The parent will see >0 if fork succeeds and -1 on failure. So you need to use that to ensure that only the parent process does the count and print. Also, your current code may fork too many processes because each forked child will also execute forks. Is that what you intend or did you want all the fork calls only in the one parent process? – kaylum Mar 24 '15 at 23:17
  • The code it's ok because I need 8 processes to be created. But in the end, I need to print "8 processes" only once after all process were created and I don't know how I can do it. – Alice Mar 24 '15 at 23:25

2 Answers2

5

There are a number of ways to do this, and a good technique is to have each child write one byte into a file descriptor which the original process can read. Note that, for the sake of brevity, the following code contains absolutely no error checking. Also, we report only the number of spawned processes (7) rather than counting the original to get a count of 8:

int main(void) {
    int fd[2];
    int depth = 0; /* keep track of number of generations from original */
    int i;
    pipe(fd);  /* create a pipe which will be inherited by all children */
    for(i=0; i<3; i++) {
        if(fork() == 0) {  /* fork returns 0 in the child */
            write(fd[1], &i, 1);  /* write one byte into the pipe */
            depth += 1;
        }
    }
    close(fd[1]);  /* exercise for the reader to learn why this is needed */
    if( depth == 0 ) { /* original process */
      i=0;
      while(read(fd[0],&depth,1) != 0)
        i += 1;
      printf( "%d total processes spawned", i);
    }

    return 0;
}
William Pursell
  • 204,365
  • 48
  • 270
  • 300
  • I think you need waits or waitpids somewhere. Otherwise you don't know when the child processes have been completely created all the way down the process hierarchy. Which would result in a count that is too low. – kaylum Mar 25 '15 at 05:56
  • 1
    You do not need a wait. The while loop will not terminate until all descendants have closed the pipe. – William Pursell Mar 25 '15 at 11:54
1

Printing the count value out just once is the easy part. Because you can get the process pid before the for loop. And then get the pid again after the for loop and only print if the pids match. For the counting part, it depends on whether your child processes exit or not. If they exit the solution is easier. The below code demonstrates one possible solution if the child processes exit (for brevity have not done full error checking). The idea is that each child process counts its own children. Parent waits for each child to complete and adds in its count. Haven't had time to fully test/debug the program so there may be some errors. But hopefully gives you the general idea.

#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>

int main(void)
{
    pid_t before_pid, after_pid;
    pid_t forked_pid;
    int count;
    int i;
    int status;

    before_pid = getpid();
    count = 1; /* count self */
    for (i = 0; i < 3; i++) {
        forked_pid = fork();

        if (forked_pid > 0) {
            waitpid(forked_pid, &status, 0);
            /* parent process - count child and descendents */
            count += WEXITSTATUS(status); 
        } else {
            /* Child process - init with self count */
            count = 1;
        }
    }

    after_pid = getpid();
    if (after_pid == before_pid) {
        printf("%d processes created\n", count);
    }

    return (count);
}
kaylum
  • 13,833
  • 2
  • 22
  • 31
  • Why this algorithm fails for i till 10? It prints 256 instead 1024 – Alice Mar 25 '15 at 19:39
  • @Alice It's because the the exit status value is typically limited to an 8-bit value on most platforms. So this approach is unlikely to work if you want to create/count large number of processes (i > 8). – P.P Oct 28 '17 at 19:32