A limit for number of threads

multithreadingprocess-management

I was wondering how many processes can I create on my machine (x64 with 8Gb of RAM and running Ubuntu). So I made simple master process which was continiously creating child processes, and that child processes were just sleeping all the time. I ended with just 11-12k processes. Then I switched processes to threads and got exactly same result.
My pid_max is set to 32768, all per-user limits are disabled. Physical memory usage is just couple of bytes. Could you tell me what prevents the system to create new threads at that point?

p.s. here is my source code for multiprocessing test written in C

#include <stdio.h>
#include <unistd.h>

int main() {
    pid_t pid;
    int count = 0;
    while (1) {
        pid = fork();
        if (pid == -1) {
            printf("total: %d\n", count);
            return 0;
        }
        if (pid == 0) {
            while (1) sleep(10);
        }
        count++;
    }
}

Best Answer

I think you hit either a number of processes limit or a memory limit.

When I try your program on my computer and reach the pid == -1 state, fork() returns the error EAGAIN, with error message: Resource temporarily unavailable. As a normal user, I could create approx 15k processes.

There are several reasons this EAGAIN could happen, detailed in man 2 fork:

  • not enough memory,
  • hitting a limit like RLIMIT_NPROC,
  • deadline scheduler specifics.

In my case, I think I just hit the RLIMIT_NPROC limit, aka what ulimit -u usually shows. The best is to display this limit within the program, so you have the real value, not your shell's limits.

#include <sys/time.h>
#include <sys/resource.h>

int main() {
    struct rlimit rlim;
    getrlimit(RLIMIT_NPROC, &rlim);
    printf("RLIMIT_NPROC soft: %d, hard: %d\n", rlim.rlim_cur, rlim.rlim_max);

Which yields:

RLIMIT_NPROC soft: 15608, hard: 15608
total: 15242

Which looks reasonable as I have other processes running, including a web browser.


Now, as root, the limits don't really apply anymore and I could fork() much more: I created more than 30k processes, close to my 32k pid_max.

Now, if I take my normal user shell's PID (echo $$), and as root in another shell, I do: prlimit --pid $SHELLPID --nproc=30000, and then launch your program in this shell, I can create almost 30k processes:

RLIMIT_NPROC soft: 30000, hard: 30000
total: 29678

Finally: you should also consider memory usage, because on my system, I used a lot of RAM and swap to create all those processes, and maybe it was the limit you hit. Check with free.

Related Question