【发布时间】:2017-11-02 14:46:11
【问题描述】:
在此处考虑这段代码 sn-p,我正在尝试创建一堆线程,这些线程最终处理模拟竞争条件的给定任务。
const int thread_count = 128;
pthread_t threads[thread_count];
for (int n = 0; n != thread_count; ++n)
{
ret = pthread_create(&threads[n], 0, test_thread_fun, &test_thread_args);
if( ret != 0 )
{
fprintf( stdout, "Fail %d %d", ret, errno );
exit(0);
}
}
除了偶尔 pthread_create 会因 errno EAGAIN “资源暂时不可用”而失败外,一切正常,我尝试诱导睡眠,然后重试创建,但没有实际效果。
故障是零星的,在某些盒子上没有故障,而在某些盒子上却非常频繁地发生。
知道这里可能出了什么问题吗?
编辑 - 1
更新最大线程数
cat /proc/sys/kernel/threads-max
256467
编辑 2
我认为这里的输入让我思考,我可能会执行以下操作并发布任何值得分享的结果。
- 将堆栈大小设置为最小值,我认为 thread_function 不使用任何大型数组。
- 增加我的记忆和交换(并消除任何副作用)
- 编写一个脚本来监控系统行为,并查看运行此案例时是否有任何其他进程/系统守护进程干扰,这反过来又会导致资源紧缩。
- 系统硬性和软性限制非常高,所以我将保持原样。
【问题讨论】:
-
手册页显示“EAGAIN 系统缺少创建另一个线程所需的资源,否则将超出系统对进程 {PTHREAD_THREADS_MAX} 中的线程总数施加的限制。”
-
128 有点多线程。
-
可用系统资源会不时变化,具体取决于系统上运行的其他内容。因此,失败没有必要“一致”。
-
新线程的默认堆栈大小通常非常大,例如 8 兆字节。线程堆栈所需的内存量通常是第一个限制因素。您可以使用
pthread_attr_init()和pthread_attr_setstacksize()创建一个描述新线程堆栈大小的pthread 属性(您可以为所有线程重用该堆栈大小)。在大多数架构上,如果线程工作者函数没有大型本地数组或深度嵌套,则 65536 字节往往可以正常工作。参见例如以here 为例。