4

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++;
    }
}
  • 1
    What does ulimit -u report? – dhag Feb 7 '17 at 22:12
  • @dhag ulimit -u reports 31127 – Andrii Maletskyi Feb 7 '17 at 22:39
  • 2
    errno should be set when pid == -1, maybe that has clues? – thrig Feb 7 '17 at 22:49
  • 1
    Please see stackoverflow.com/questions/344203/… for more information. – Elastic Lamb Feb 7 '17 at 22:56
  • 1
    But these bottlenecks are hitting painfully long before you reach hard limits (on number of threads or processes). So you really should benchmark your actual code. – Basile Starynkevitch Feb 8 '17 at 14:43
4

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.

| improve this answer | |
  • Control group tasks maxima have an effect too, in addition to POSIX resource limits; quite famously on systemd operating systems like Ubuntu 15 and 16. – JdeBP Feb 9 '17 at 16:48

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.