线程数的限制是多少?

线程数的限制是多少?

我想知道我的机器(具有 8Gb RAM 并运行 Ubuntu 的 x64)上可以创建多少个进程。所以我制作了简单的主进程,它不断创建子进程,并且子进程一直在休眠。我最终只有 11-12k 个进程。然后我将进程切换为线程并得到完全相同的结果。我的 pid_max 设置为 32768,所有每用户限制均被禁用。物理内存使用量仅为几个字节。你能告诉我是什么阻止系统在此时创建新线程吗?

ps 这是我用 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

我认为您达到了进程数限制或内存限制。

当我在我的计算机上尝试您的程序并达到pid == -1状态时,fork()返回 error EAGAIN,并显示错误消息:Resource temporarily unavailable作为普通用户,我可以创建大约 15k 个进程。

EAGAIN发生这种情况的原因有多种,详细信息如下man 2 fork

  • 内存不足,
  • 达到 RLIMIT_NPROC 等限制,
  • 截止日期调度程序细节。

就我而言,我认为我刚刚达到了RLIMIT_NPROC极限,也就是ulimit -u通常所显示的那样。最好是在程序中显示此限制,这样您就可以获得真正的值,而不是 shell 的限制。

#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);

得出的结果是:

RLIMIT_NPROC soft: 15608, hard: 15608
total: 15242

这看起来很合理,因为我正在运行其他进程,包括网络浏览器。


现在,作为根用户,这些限制不再适用,而且我可以做得fork()更多:我创建了超过 30k 的进程,接近我的 32k pid_max

现在,如果我把我的普通用户shell 的 PID ( echo $$),以及作为根用户在另一个外壳中,我这样做:prlimit --pid $SHELLPID --nproc=30000,和然后在这个 shell 中启动你的程序,我可以创建近 30k 个进程:

RLIMIT_NPROC soft: 30000, hard: 30000
total: 29678

最后:您还应该考虑内存使用情况,因为在我的系统上,我使用很多RAM 和交换来创建所有这些进程,也许这是你达到的限制。检查与free.

相关内容