4

The code below will spawn as many children as possible. Themselves won't fork further, and will become zombies once the parent process exits.
How many children processes will the parent process spawn ?

int main(int argc, char *arg[])
{
     while(fork() > 0);
}
Quentin
  • 62,093
  • 7
  • 131
  • 191
Moawiya
  • 147
  • 1
  • 2
  • 11
  • I don't know if efficiency is requested in this, but `while(fork() >= 0)` would be better. or worse, depending on who the owner is. – holgac Apr 13 '15 at 12:49
  • 1
    if I add >= the sons also make sons and I don't want that. – Moawiya Apr 13 '15 at 12:58
  • 1
    Zombie processes still have their pids assigned, so [max_pids](http://stackoverflow.com/questions/6294133/maximum-pid-in-linux) might be your limit if you have enough memory to hold process data. – holgac Apr 13 '15 at 13:05

3 Answers3

9

The number of child processes can be limited with setrlimit(2) using RLIMIT_NPROC. Notice that fork(2) can fail for several reasons. You could use bash builtin ulimit to set that limit.

You can use getrlimit (or parse /proc/self/limits, see proc(5)) to get that information.

System-wide, you might use /proc/sys/kernel/threads-max since:

This file specifies the system-wide limit on the number of threads (tasks) that can be created on the system.

There is also /proc/sys/kernel/pid_max

This file specifies the value at which PIDs wrap around (i.e., the value in this file is one greater than the maximum PID). PIDs greater than this value are not allocated; thus, the value in this file also acts as a system-wide limit on the total number of processes and threads. The default value for this file, 32768, results in the same range of PIDs as on earlier kernels. On 32-bit platforms, 32768 is the maximum value for pid_max. On 64-bit systems, pid_max can be set to any value up to 2^22 (PID_MAX_LIMIT, approximately 4 million).

However, there could be other limitations (notably swap space).

A task for the kernel is either a single-threaded process or some thread inside some process - e.g. created by low-level syscall clone(2) (or some kernel thread like kworker, ksoftirqd etc...).

BTW, the practical number of processes is much more limited by available resources. A typical Linux desktop has only a few hundreds of them (right now, my Debian/x86-64 desktop with 32Gb RAM & i5-4690S has 227 processes). So a process is a quite expensive resource (it needs RAM, it needs CPU...). If you have too many of them you'll experience thrashing. And in practice, you don't want to have too many runnable processes or schedulable tasks (probably only a few dozens of them at most, perhaps no more than a few per core).

Basile Starynkevitch
  • 223,805
  • 18
  • 296
  • 547
4

Update -- I was perhaps to fast, didn't see that there is no fork loop. Then it's probably depending on how expensive it is to fork on that machine. The zombies may also use system resources which will at some point be exhausted. And the ulimit command mentioned below is of course still valid.--

Update 2: I see this in some copy of /linux/kernel/fork.c which should keep a machine usable (max_threads apparently limits the number of processes as well since each process has at least one thread):

         /*
272          * The default maximum number of threads is set to a safe
273          * value: the thread structures can take up at most half
274          * of memory.
275          */
276         max_threads = mempages / (8 * THREAD_SIZE / PAGE_SIZE);

-- Original answer:

It will create as many processes as are physically possible (that is, it will quickly freeze the machine -- I have done that), or as many as are allowed for the current user or shell, if such a limit is imposed. In bash one can impose a limit through the built-in shell command ulimit -u <number>. Note that a process probably doesn't have to be started through bash (perhaps a cron job won't).

Peter - Reinstate Monica
  • 15,048
  • 4
  • 37
  • 62
  • I think your answer is still valid, since zombie processes are still children. The children won't be using much memory though, they will only have a `task_struct` in kernel, with only few unique valid pointers. others will either be null when the process becomes zombie, or they will be the same as parents'. – holgac Apr 13 '15 at 12:53
0

Just in case, in addition to @Peter - Reinstate Monica answer, Linux kernel 5.18 has it this way:

/include/uapi/linux/futex.h:

// ...

/*
 * The rest of the robust-futex field is for the TID:
 */
#define FUTEX_TID_MASK      0x3fffffff

// ...

/kernel/fork.c:

// ...
#include <linux/futex.h>

// ...
/*
 * Minimum number of threads to boot the kernel
 */
#define MIN_THREADS 20

/*
 * Maximum number of threads
 */
#define MAX_THREADS FUTEX_TID_MASK

// ...
static int max_threads;     /* tunable limit on nr_threads */

// ...
/*
 * set_max_threads
 */
static void set_max_threads(unsigned int max_threads_suggested)
{
    // ...
    max_threads = clamp_t(u64, threads, MIN_THREADS, MAX_THREADS);
}

// ...
void __init fork_init(void)
{
    // ...
    set_max_threads(MAX_THREADS);
    // ...
}

// ...
/*
 * This creates a new process as a copy of the old one,
 * but does not actually start it yet.
 *
 * It copies the registers, and all the appropriate
 * parts of the process environment (as per the clone
 * flags). The actual kick-off is left to the caller.
 */
static __latent_entropy struct task_struct *copy_process(
    // ...
)
{
    // ...
    /*
     * If multiple threads are within copy_process(), then this check
     * triggers too late. This doesn't hurt, the check is only there
     * to stop root fork bombs.
     */
    retval = -EAGAIN;
    if (data_race(nr_threads >= max_threads))
        goto bad_fork_cleanup_count;
    // ...
}

//...

Regarding "TID":

gettid() returns the caller's thread ID (TID). In a single-threaded process, the thread ID is equal to the process ID (PID, as returned by getpid(2)).

Source: https://man7.org/linux/man-pages/man2/gettid.2.html

Artfaith
  • 1,183
  • 4
  • 19
  • 29