【问题标题】:Pthreads - out of memory?Pthreads - 内存不足?
【发布时间】:2011-04-07 17:43:40
【问题描述】:

我正在用 C 编写一些东西,在 Linux 中创建了很多 Pthread。

当我用少量线程运行程序时,它可以工作,但是一旦我让它创建大约 1000 个线程,它就会出错。现在设置了errno 标志,但我想知道是哪一个问题导致了它。 EAGAINEINVALELEMULTITHREADFORKENOMEM

有什么方法可以查出是不是这些错误之一,如果是,是哪一个?

【问题讨论】:

  • 1000 个线程 == 修复您的设计。
  • 我知道这有点离题,但你需要创建那么多线程吗?是否可以使用线程池 (en.wikipedia.org/wiki/Thread_pool) 实现您的设计?
  • 1000个甚至100000个线程都没有问题。一个好的实现可以很好地处理它们。
  • 1000 个线程 == 购买更大的计算机和/或尝试不同的操作系统。
  • 由于 glibc 荒谬的默认堆栈大小,每个人都忽略了 OP 只是用完了虚拟地址空间。

标签: c linux unix pthreads stack-overflow


【解决方案1】:

我相信您正在寻找的是pthread_attr_setstacksize 函数。默认情况下,glibc 为每个线程的堆栈保留 2MB、8MB 或 10MB 或内存。按照这个速度,您将很快耗尽 32 位机器上的虚拟地址空间,并且即使在 64 位机器上也很快耗尽提交费用。

pthread_t td;
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_attr_setstacksize(&attr, 32768);
pthread_create(&td, &attr, start_function, start_art);
pthread_attr_destroy(&attr);

这段代码过于简单了;当然,您可能想要检查其中一些调用是否失败。实际上,这就是您最初提出的问题。 pthread_* 函数几乎所有返回错误代码作为其返回值,而不是在errno,所以errno 不能用于检查结果,perror 将不起作用,除非你指定返回值到errno。相反,请执行以下操作:

result = pthread_create(&td, &attr, start_function, start_art);
switch (result) {
case EINVAL: /* ... */
case EAGAIN: /* ... */
/* etc. */
}

【讨论】:

    【解决方案2】:

    perror() 应该可以解决问题。

    在你的 linux 系统上执行man 3 perror

    【讨论】:

    • 是的,如果您刚刚打印出 errno,因此会留下类似“22”的内容,然后查看 /usr/include/*errno.h 文件中的定义。在大多数 Linux 系统上,您都在寻找 /usr/include/asm-generic/errno-base.h
    【解决方案3】:

    只是为了俗气的测试:

    int ret;
    pthread_t tid;
    
    if ((ret = pthread_create(&tid, NULL, startfunc, NULL)) != 0)
    {
        errno = ret;
        perror("pthread_create");
    }
    

    R 是正确的,默认堆栈大小会用那么多线程消耗内存。

    【讨论】:

      猜你喜欢
      • 2014-10-15
      • 2011-11-06
      • 2011-05-21
      • 2021-12-20
      • 2021-10-29
      • 1970-01-01
      • 2011-03-28
      • 2020-03-12
      • 2015-08-11
      相关资源
      最近更新 更多