【问题标题】:pthread_create fails with EAGAINpthread_create 因 EAGAIN 失败
【发布时间】: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

我认为这里的输入让我思考,我可能会执行以下操作并发布任何值得分享的结果。

  1. 将堆栈大小设置为最小值,我认为 thread_function 不使用任何大型数组。
  2. 增加我的记忆和交换(并消除任何副作用)
  3. 编写一个脚本来监控系统行为,并查看运行此案例时是否有任何其他进程/系统守护进程干扰,这反过来又会导致资源紧缩。
  4. 系统硬性和软性限制非常高,所以我将保持原样。

【问题讨论】:

  • 手册页显示“EAGAIN 系统缺少创建另一个线程所需的资源,否则将超出系统对进程 {PTHREAD_THREADS_MAX} 中的线程总数施加的限制。”
  • 128 有点多线程。
  • 可用系统资源会不时变化,具体取决于系统上运行的其他内容。因此,失败没有必要“一致”。
  • 新线程的默认堆栈大小通常非常大,例如 8 兆字节。线程堆栈所需的内存量通常是第一个限制因素。您可以使用pthread_attr_init()pthread_attr_setstacksize() 创建一个描述新线程堆栈大小的pthread 属性(您可以为所有线程重用该堆栈大小)。在大多数架构上,如果线程工作者函数没有大型本地数组或深度嵌套,则 65536 字节往往可以正常工作。参见例如以here 为例。

标签: c linux pthreads


【解决方案1】:

如果您的程序确保它不会创建超过系统限制允许的线程数(通过在创建新线程之前加入线程),那么您很可能会遇到这个内核错误:

使用某些类型的容器技术,竞争窗口看起来要大得多,并且更容易触发错误。 (这可能取决于使用的 cgroup 类型。)

【讨论】:

    【解决方案2】:

    您可能对每个进程的最大线程数有系统限制。尝试通过以下方式查看它: cat /proc/sys/kernel/threads-max

    【讨论】:

      【解决方案3】:

      在你的 shell 中检查ulimit -a。您可能在登录策略中设置了进程限制,而 Linux 荒谬地将其应用于线程。

      【讨论】:

        【解决方案4】:

        没有足够的资源来启动一个新线程。 检查系统上是否有僵尸线程,或者系统上是否有足够的内存等。

        【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-01-01
        • 1970-01-01
        • 2011-07-10
        • 2019-03-18
        • 1970-01-01
        相关资源
        最近更新 更多