为什么我不能在 Linux 中创建 50k 个进程?

Why can't I create 50k processes in Linux?

使用Linux

$ uname -r
4.4.0-1041-aws
$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 16.04.3 LTS
Release:    16.04
Codename:   xenial

限制最多允许 200k 个进程

$ ulimit -a
core file size          (blocks, -c) 0
data seg size           (kbytes, -d) unlimited
scheduling priority             (-e) 0
file size               (blocks, -f) unlimited
pending signals                 (-i) 563048
max locked memory       (kbytes, -l) 64
max memory size         (kbytes, -m) unlimited
open files                      (-n) 524288
pipe size            (512 bytes, -p) 8
POSIX message queues     (bytes, -q) 819200
real-time priority              (-r) 0
stack size              (kbytes, -s) 8192
cpu time               (seconds, -t) unlimited
max user processes              (-u) unlimited
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited
$ cat /proc/sys/kernel/pid_max
200000
$ cat /proc/sys/kernel/threads-max
1126097

并且有足够的可用内存为 127k 个进程分配 1MB

$ free
              total        used        free      shared  buff/cache   available
Mem:      144156492     5382168   130458252      575604     8316072   137302624
Swap:             0           0           0

我现有的不到 1k processes/threads。

$ ps -elfT | wc -l
832

但是我无法启动 50k 个进程

$ echo '
seq 50000 | while read _; do
    sleep 20 &
done
' | bash
bash: fork: retry: Resource temporarily unavailable
bash: fork: retry: Resource temporarily unavailable
bash: fork: retry: Resource temporarily unavailable
bash: fork: retry: Resource temporarily unavailable
bash: fork: retry: Resource temporarily unavailable
bash: fork: retry: Resource temporarily unavailable
...

为什么我不能创建 50k 个进程?

因为每个process都需要一些资源:一些RAM(包括一些内核内存),一些CPU,等等

每个进程都有自己的virtual address space, including its own call stack (and some of it requires physical resources, including several pages of RAM; read more about resident set size;在我的桌面上,某些 bash 进程的 RSS 大约为 6Mbytes)。所以进程其实是一些很重的东西。

顺便说一句,这不是特定于 Linux。

阅读更多关于操作系统的信息,例如Operating Systems : Three Easy Pieces

也可以尝试 cat /proc/$$/mapscat /proc/$$/status 并阅读有关 proc(5). Read about failure of fork(2) and of execve(2). The resource temporarily unavailable is for EAGAIN (see errno(3) 的更多信息),并且 有多种原因会导致 fork 失败并显示 EAGAIN。在我的系统上,cat /proc/sys/kernel/pid_max 给出 32768(达到该限制给出 EAGAIN for fork)。

顺便说一句,想象一下如果您可以 分叉一万个进程。然后 context switch 时间将占主导地位 w.r.t。到运行宁时间。

您的 Linux 系统看起来像一些 AWS 实例。亚马逊不会让你创建那么多进程,因为他们的硬件要求不高。

(在一些昂贵的超级计算机或服务器上,例如 1 TB 的 RAM 和一百个内核,也许你 可以 运行 50K 个进程;我猜他们需要一些特定的内核或内核配置。我建议从亚马逊支持那里获得帮助)

根据@Basile 的回答,您可能 运行 没有 pids。

cat /proc/sys/kernel/pid_max 在我的机器上给出了 32768(带符号短的最大值)。小于 50k

编辑: 我错过了 /proc/sys/kernel/pid_max 设置为 200000。在这种情况下这可能不是问题所在。

Linux癌症systemd引起的

除了kernel.pid_max和ulimit,我还需要更改第三个限制。

/etc/systemd/logind.conf

[Login]
UserTasksMax=70000

然后重启。