Search code examples
cfork

How many threads will be created by given C fork code


Consider the code given below:

#include <stdio.h> 
#include <unistd.h> 
int main() 
{ 
   fork(); 
   fork() && fork() || fork(); 
   fork();
   printf("forked\n"); 
   return 0; 
}

The question is how many times forked wil be printed. As per my analysis, it should be printed 20 times. Also this answer confirms the same.

However when I run the code on onlinegdb.com and ideone.com, they print it 18 and 5 times respectively. Why so?


Solution

  • Your code don't create any threads. These are called Pthreads on Linux and you'll use pthread_create(3) (which internally uses clone(2)) to create them.

    Of course, your code is using (incorrectly) fork(2) so it creates processes (unless fork is failing). Notice that fork is difficult to understand (and to explain, so I won't even try here). You may need to read a lot about it, e.g. fork wikipage, ALP, and perhaps Operating Systems: Three Easy Pieces (both have several chapters explaining it).

    You should handle the failure of fork. As explained here, there are three cases to consider for each fork, and you'll better rewrite your code to do at most one fork per statement (an assignment like pid_t pida = fork();)

    BTW, you'll better flush standard streams (and the data in their buffers) before every fork. I recommend using fflush(3) by calling fflush(NULL); before every fork.

    Notice that each process has its own (unique) pid (see getpid(2) and credentials(7)). You might understand things better if you print it, so try using something like
    printf("forked in %ld\n", (long) getpid());

    when I run the code

    You really should run that code on your computer under Linux. Consider installing a Linux distribution (perhaps in some virtual machine) on your laptop or desktop. Notice that Linux is very developer- and student- friendly, and it is mostly made of free software whose source code you can study.

    they print it 18 and 5 times respectively. Why so?

    Free web services should limit the resources used by outside clients (on Linux, they probably would use setrlimit(2) for that purpose). Obviously, such sites -giving the ability to run nearly arbitrary C code- want to avoid fork bombs. Very likely, some of your fork-s failed on them (and since your original code don't check for failures, you did not notice that).

    Even on your own desktop, you could not create a lot of processes. As a rule of thumb, you might have a few hundreds processes on your computer with most of them being idle (waiting, perhaps with poll(2) or a blocking read(2), etc, ... for some IO or for some timeout, see also time(7)), and only a dozen of them being runnable (by the process scheduler of your kernel). In other words, a process is quite a costly computing resource. If you have too many runnable processes you could experiment thrashing.

    Use ps(1) and top(1) (and also htop and pgrep(1)) to query the processes on your Linux system. If you want to do that programmatically, use /proc/ (and see proc(5) for more) - which is used by ps, top, pgrep, htop etc...