首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >ENOMEM创建线程失败的原因?

ENOMEM创建线程失败的原因?
EN

Stack Overflow用户
提问于 2010-12-26 00:26:39
回答 4查看 1.9K关注 0票数 2

我有一个应用程序,它在主线程中使用pthread_create()pthread_detach(),稍后在子线程中使用pthread_exit()

在大约54个pthread_create()调用之后,每个调用都与随后的pthread_detach()配对,然后pthread_exit()pthread_create()将失败。这是ENOMEM故障“内存不足”。

什么可能导致pthread_exit()无法释放旧线程的内存,并导致应用程序泄漏内存并最终耗尽内存?

它在Linux Centos 5 64位上运行,但它是一个32位构建的应用程序。

下面是创建同时调用pthread_create()pthread_detach()的线程的代码。

代码语言:javascript
复制
int
_createThread()
{
  pthread_attr_t attr;
  int return_val;

  return_val = setupMutex(_Mtx());

  if (return_val != 0) {
    return return_val;
  }

  return_val = setupCond(_StartCond());

  if (return_val != 0) {
    return return_val;
  }

  return_val = setupCond(_EndCond());

  if (return_val != 0) {
    return return_val;
  }

  return_val = pthread_attr_init(&attr);

  if (return_val != 0) {
    return -1;
  }

  size_t stackSize = 1024 * 1024 * 64; // Our default stack size 64MB.

  return_val = pthread_attr_setstacksize(&attr, stackSize);

  if (return_val != 0) {
    return -1;
  }

  int tries = 0;

 retry:
  // _initialize() gets called by the thread once it is created.
  return_val = pthread_create(&_threadId, &attr,
                              (void *(*)(void *))_initialize,
                              (void *)this);

  if (return_val != 0) {
    if (return_val == EAGAIN) {
      if (++tries < 10) {
        Exit::deferredWarning(Exit::eagainThread);
        goto retry;
      }
    }
    return -1;
  }

  return_val = pthread_attr_destroy(&attr);

  if (return_val != 0) {
    return -1;
  }

  return_val = pthread_detach(_threadId);

  if (return_val != 0) {
    return -1;
  }

  // Wait for the new thread to finish starting up.
  return_val = waitOnCond(_Mtx(), _EndCond(), &_endCount, 10 /* timeout */, 0,
                          "_createThread-end");

  if (return_val != 0) {
    return -1;
  }

  return 0;
}

void
_exitThread()
{
  (void) releaseCond(_Mtx(), _EndCond(), &_endCount, "_exitThread-end");
  pthread_exit(NULL);
}
EN

回答 4

Stack Overflow用户

发布于 2010-12-26 00:34:49

pthread_exit之前调用pthread_exit,以便线程可以在退出前进行清理。

票数 4
EN

Stack Overflow用户

发布于 2016-08-25 16:00:47

pthread_create的手册页中提供了相关说明:

当分离的线程终止时,它的资源会自动释放回系统,而不需要另一个线程加入终止的线程

因此,如果你既不分离它,也不加入它,你就会释放一些资源,这最终会引发ENOMEM。

您应该分离线程或将其与其父线程联接。

票数 2
EN

Stack Overflow用户

发布于 2010-12-28 23:45:56

威尔,我删除了我以前的答案,因为我好像弄错了。沿着这条线,我有一个问题:你是如何获得ENOMEM的?你有没有像我在答案中指出的那样勾选"errno“?因为pthread_create是规则的一个例外,并且没有设置errno;相反,错误将作为结果返回。

获取失败原因的正确方法:

代码语言:javascript
复制
int err = pthread_create(...);
if(err)
{
    perror( "Error creating thread" );
    printf( "Error: %s\n", strerror( err ) );
    return false;
}

我这么问的原因是因为pthread_create永远不会因为ENOMEM而失败!如果没有内存,pthread_create将返回EAGAIN。有关EAGAIN与ENOMEM的信息,请参阅http://sourceware.org/ml/glibc-bugs/2007-11/msg00007.html

编辑

显而易见的问题:系统确实有足够的空闲内存,对吧?

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4530787

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档