为什么我不能在 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/$$/maps
和 cat /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
然后重启。
使用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/$$/maps
和 cat /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
然后重启。