【问题标题】:pthread_create ENOMEM around 32000 threadspthread_create ENOMEM 大约 32000 个线程
【发布时间】:2010-08-05 21:24:54
【问题描述】:

运行的进程卡在 32 000 (± 5%) 左右

~# cat /proc/sys/kernel/threads-max 127862

~# ulimit -s 堆栈大小 (kbytes, -s) 2048

可用内存:3,5 Go

当我在进程卡在“top”时尝试基本命令时,我收到 bash 消息:无法分叉,内存不足。 即使还有 3,5 Go 的空闲内存。

什么可以限制线程创建在 32 000 ?

【问题讨论】:

  • threads-max 值是系统范围的限制。也可能有每个进程的限制。但是为什么你会想要/需要那么多线程呢?是综合调度程序测试吗?
  • 在 FreeBSD 上,是的,但不是在 debian 上,使用的是分发版...用于对 Core i7 进行压力测试
  • 我认为您是在对调度程序进行压力测试,而不是对 cpu 进行压力测试。
  • 是什么让您认为您正在通过创建数千个线程来对 CPU 进行压力测试?您不是,您正在对操作系统和线程调度程序进行压力测试。您的 CPU 只有固定数量的内核,因此它一次只能运行固定数量的线程。如果你想对 CPU 进行压力测试,你需要尽量减少所有其他可能导致 CPU 停滞的因素——例如页面错误和内存延迟,如果你希望操作系统不断切换,这两者都会有很多在运行 32000 个线程之间,每个线程在 RAM 中各自​​的位置都有自己的堆栈。

标签: c++ multithreading pthreads


【解决方案1】:

线程通过线程 ID (TID) 进行标识,在 Linux 中它们只是 PID,并且...

~% sysctl kernel.pid_max
kernel.pid_max = 32768

Linux 中的 PID 是 16 位的,32768 已经是允许的最大值。有了这么多线程,你刚刚完全填满了操作系统进程表。我认为您无法创建比这更多的线程。

无论如何,如果您需要这么多线程,那么您的设计确实有问题。真的没有理由拥有这么多。

【讨论】:

  • 根据man gettid 在我的系统线程ID 不是PID。仅对于单线程应用程序,线程 id 与 PID 相同。
  • 另外,我系统上的pid_t 似乎最终解析为int。
  • 看来成功了!谢谢朱利亚诺!是的,我知道设计被破坏了,我们只需要在 Core i7 上做一些基准测试,看看它从线程切换到线程的速度有多快
  • @user374215:gettid(2) 提到的是关于 PID 和 TID 的语义。是的,它们是不同的。但是在内部进程表中,进程和线程共享同一个命名空间,并且该命名空间受kernel.pid_max的限制。
  • 实际上服务器并没有给我通常的“Fork”问题....但是线程数仍然停留在±32000这很烦人!
【解决方案2】:

差不多 10 年后:内核 5.6。 kernel/fork.c 中有一个限制:参见 max_threads/2。

但主要的罪魁祸首是 mmap。见strace 输出:

mprotect(0x7fbff49ba000, 8388608, PROT_READ|PROT_WRITE) = -1 ENOMEM(不能>分配内存)

增加/proc/sys/vm/max_map_count 以获得更多线程。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-09-22
    • 1970-01-01
    • 1970-01-01
    • 2014-04-24
    • 1970-01-01
    • 2021-09-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多