我注意到当我使用表单
中的线程调用方法时////main code/////
pthread_t thread;
pthread_create(thread,function,data);
//////////////////
void* function(void* data){
//work with some data on the heap via a vector on the stack
std::vector<double> variable (100,1.2345);
//do contents of thread
pthread_exit(NULL);
}
尽管没有调用new
(除了隐式地在向量变量中),我得到内存泄漏,内存使用量与我以这种方式调用function
的次数呈线性关系。 / p>
但是,如果我这样做
void* function(void* data){
{
std::vector<double> variable (100,1.2345);
//do contents of thread
}
pthread_exit(NULL);
}
不会发生内存泄漏。
似乎pthread_exit(NULL)
没有清除堆栈变量,就像你在使用return
的正常函数结束时得到的那样(我说的正确吗?!)所以把它们放在他们的自己的范围确保他们获得自由。
然而,这似乎是一个巨大的kludge。退出pthread时,如何确保正确清除堆栈变量(及其在容器方面的内容)?
答案 0 :(得分:2)
似乎
pthread_exit(NULL)
没有清除堆栈变量,就像你在返回的正常函数结束时得到的那样(我对此是正确的吗?!)
这就像在非线程代码中调用exit(0)
一样,程序立即退出并且不会展开堆栈。 (由于pthreads规范是用C语言定义的,而不是C ++,它没有定义C ++析构函数会发生什么,所以它是特定于平台的。)
所以将它们放在自己的范围内可以确保它们被释放。
因为这样,向量的析构函数会在您调用pthread_exit()
之前运行。
退出pthread时,如何确保正确清除堆栈变量(及其在容器方面的内容)?
只需从线程函数返回,您就不需要使用pthread_exit
退出线程启动函数(传递给pthread_create
的函数)。 POSIX说:
当第一次调用
pthread_exit()
的线程以外的线程从用于创建它的启动例程返回时,对main()
进行隐式调用。
和GNU/Linux man page的说法略有不同:
从除以外的任何线程的start函数执行返回 主线程导致对
pthread_exit()
的隐式调用,使用 函数的返回值作为线程的退出状态。
您可以使用pthread_exit
从堆栈中的其他函数退出线程,就像您可以使用exit()
退出程序而不是从main()
返回,但是最外面的函数只是return NULL;
(或者你想要的任何返回值)。
使用pthread_exit(x)
的唯一时间只是return x;
位于main
,这会导致程序等待其他线程完成。
答案 1 :(得分:0)
对new()
的调用隐藏在std::vector<>
实施中。
在您的第一个代码示例中,pthread_exit(NULL);
将在调用std::vector<>
析构函数之前退出该线程,从而导致内存泄漏。
你的第二个例子强制在std::vector<>
之前调用pthread_exit(NULL);
的析构函数。
答案 2 :(得分:0)
(好吧,我可以看到其他人已经解决了这个问题......是的,这只适用于可连接的线程。如果你试图分离不可连接的线程,你会引发错误。)
您需要在退出时调用pthread_detach(...)
配置pthread以进行资源回收。
这不是为了使任何其他答案无效。但是,如果要在退出时回收堆栈空间,则需要分离任何未加入的可连接子线程!你为什么不想要那个?
即使您通过代码更改解决了这个特定的泄漏,如果您要使用C / C ++中的子线程进行编程,也需要继续使用此知识。 std::thread
和boost::thread
有类似的要求。