ENOMEM无法创建线程的原因?

时间:2010-12-25 16:26:39

标签: c++ memory-leaks 64-bit pthreads centos5

我的应用程序在主线程中使用pthread_create()pthread_detach(),在子线程中使用pthread_exit()

在大约54个pthread_create()来电后,pthread_detach()再与pthread_exit() pthread_create()配对,ENOMEM失败。 pthread_exit()失败“内存不足”。

什么可能导致pthread_create()没有释放旧线程的内存并导致我的应用程序泄漏内存并最终耗尽?

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

以下是创建调用pthread_detach()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); } 的线程的代码。

{{1}}

4 个答案:

答案 0 :(得分:4)

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

答案 1 :(得分:2)

解释见pthread_create的手册页:

  

当分离的线程终止时,它的资源是   在不需要的情况下自动释放回系统   另一个与终止线程

连接的线程

所以,如果你没有分离它,那么加入你就会失去一些资源,最终会引发ENOMEM。

您应该分离线程或将其从其父线程中加入。

答案 2 :(得分:1)

答案 3 :(得分:0)

如果加入对您的用例不起作用,请致电pthread_join()pthread_detatch()

发生此错误是因为库存储了所有已终止线程的退出代码,等待通过pthread_join()将其传回给您。或者,如果您不关心线程的退出代码,请在创建后调用pthread_detatch()。这告诉API你不关心它的返回码,所以它不需要存储它。