当线程数超过32705时,出现Boost::thread_resource_error错误

boost::thread_resource_error when more than 32705 threads

本文关键字:thread resource 错误 error Boost 出现 线程 32705时      更新时间:2023-10-16

我正在实现一个消息传递算法。消息通过图的节点传播,直到它们(从其他邻居)接收到足够的信息来发送消息为止。

如果我将每个消息放在自己的线程中,并使用boost::条件暂停线程,直到所有所需的信息可用,则算法很容易编写。我创建了成千上万个线程,但大多数时候只有少数线程是活跃的。这似乎很有效。

我的问题是,当单元测试时,我发现如果我创建了超过32705个线程,我得到

unknown location(0):致命错误"Tree_test":std::例外:boost:: thread_resource_error

我不知道是什么原因导致的,也不知道如何修复。

似乎有足够的内存可用(每个线程只持有两个指针——消息传递的对象)。

从这个问题:Linux中每个进程的最大线程数?我认为以下信息是相关的(尽管我真的不知道其中任何一个是什么意思…)

~> cat /proc/sys/kernel/threads-max
1000000

(我从60120增加了这个-我需要重新启动吗?)

 ~>ulimit -a
core file size          (blocks, -c) 0
data seg size           (kbytes, -d) unlimited
scheduling priority             (-e) 20
file size               (blocks, -f) unlimited
pending signals                 (-i) 16382
max locked memory       (kbytes, -l) 64
max memory size         (kbytes, -m) unlimited
open files                      (-n) 1024
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

我试着摆弄挂起的信号(我的限制非常接近这个数字的2*)和堆栈大小与ulimit -S -i 8191 -(我不能增加它),但这些变化似乎没有任何影响)

我用的是64位的Ubuntu-10-10,如果有帮助的话…

我认为系统上有32K线程,您应该考虑潜在的解决方案,而不是如何拥有更多线程。例如,线程池(Boost对此有一些功能)。

无论如何,在您的系统上,pid不是被限制为32768或其他类似的值吗?你迟早会用完的,我认为最好把系统设计成允许处理比最大线程数更多的项目。

也就是说,查看/proc/sys/kernel/pid_max以查看您的最大PID—并尝试增加它。这可能会使您超过32K(但也可能导致程序的意外行为,这些程序不是为异常大的pid设计的,所以要小心)。

然后您可能会受到堆栈空间(与虚拟内存空间相反)的限制。如果你愿意,你可以尝试用更小的堆栈创建线程。

好的,要回答这个问题:你需要增加

/proc/sys/vm/max_map_count

如下所述:

https://listman.redhat.com/archives/phil-list/2003-August/msg00025.html

:

http://www.kegel.com/c10k.html limits.threads

然而,为了更好地做到这一点,请查看后面的问题:

等待条件的非线程替代方案。(编辑:Proactor模式与boost.asio?)

这实际上取决于你的堆栈有多大,但是如果你创建很多线程,你将耗尽地址空间(32位)或虚拟内存(64位)。

在Linux pthreads默认的堆栈大小是10Mb上次我检查;这意味着32k线程使用320G的地址空间(注意它可能是惰性初始化的,所以它不会使用那么多的虚拟内存);这可能太多了。

即使你把堆栈弄得很小,并且不以这种方式耗尽内存,32k线程也会为堆栈使用大量的虚拟内存。考虑使用不同的方法。

ulimit只影响初始线程的堆栈大小(在Linux下通常是动态的);其他线程的堆栈大小是固定的,并在线程创建时由pthread库设置。