当线程数超过32705时,出现Boost::thread_resource_error错误
boost::thread_resource_error when more than 32705 threads
我正在实现一个消息传递算法。消息通过图的节点传播,直到它们(从其他邻居)接收到足够的信息来发送消息为止。
如果我将每个消息放在自己的线程中,并使用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库设置。
- 在std::thread中,joinable()然后join()线程安全吗
- Visual Studio在尝试读取resource.txt文件时崩溃
- <Windows>为什么 std::thread::native_handle 返回类型为"long long unsigned int"的值,而不是 void*(又名 HANDLE)?
- 分离一个静态常量 std::thread?
- 尝试使用 std::vector<std::thread时出现静态断言失败错误>
- 使用 thread 类在 C++ 中构造线程的动态数组时出错
- 当指向对象的指针作为参数传递给 std::thread 时,内存可见性
- 如何从 std::thread 返回值
- 在C++中使用并行化的预期速度是多少(不是 OpenMp,而是 <thread>)
- 将 std::thread by 值推送到列表中
- 转发变量参数列表以模拟 std::thread
- 嵌入式设备 -> std::thread -> FreeRTOS?
- 对 'std::thread::_M_start_thread CMake 的未定义引用进行基准测试
- std::thread 增加 DLL 引用计数,从而防止卸载 DLL
- Windows 资源管理器中的图标在使用 resource.rc 时显示 2 个不同的图标
- 如何防止 std::thread 在 QT 中冻结 GUI?
- 对带有唯一指针的 std::thread 使用类成员函数时出现编译错误
- C++ - Thread Pool
- 为什么参数在构造 std::thread 时移动两次
- std::thread::_Invoker 使用线程编程时出错