我有一个应用程序,它在主线程中使用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()的线程的代码。
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);
}发布于 2010-12-26 00:34:49
在pthread_exit之前调用pthread_exit,以便线程可以在退出前进行清理。
发布于 2016-08-25 16:00:47
pthread_create的手册页中提供了相关说明:
当分离的线程终止时,它的资源会自动释放回系统,而不需要另一个线程加入终止的线程
因此,如果你既不分离它,也不加入它,你就会释放一些资源,这最终会引发ENOMEM。
您应该分离线程或将其与其父线程联接。
发布于 2010-12-28 23:45:56
威尔,我删除了我以前的答案,因为我好像弄错了。沿着这条线,我有一个问题:你是如何获得ENOMEM的?你有没有像我在答案中指出的那样勾选"errno“?因为pthread_create是规则的一个例外,并且没有设置errno;相反,错误将作为结果返回。
获取失败原因的正确方法:
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
编辑
显而易见的问题:系统确实有足够的空闲内存,对吧?
https://stackoverflow.com/questions/4530787
复制相似问题