线程耗内存问题解决
问题提出
为了解决其它的问题,不得不加一个线程,程序不卡在那里,之前加了一个线程实际测试发现占用了
非常多的内存。
解决:
多线程内存占用分析
参考链接:linux多线程内存占用分析
分析的结论,每多起一个线程,会多占用一些内存空间,多出来的内存空间实际是
为每个线程默认分配的栈空间,(线程和进程的资源是共用的,但是栈空间是要重新
分配的。)
虽然多线程在运行时是共享内存空间的,但是各个线程之间的栈区还是是相对独立的,
linux操作系统给线程默认分配了8192k bytes的栈空间,这个大小是操作系统的一个
默认值,使用ulimite -s可以查看到。
线程技术资源自动释放
参考链接:linux C语言 线程资源释放
最近做了多线程并发网络编程的时候出现了一个问题。程序在运行的过程中,占用的内存会越
来越大。起初我怀疑是程序有指针没有被free,导致内存泄漏。在查代码的过程中我发现,我
并没有手动收回创建的线程资源。通过上网查阅linux线程资源回收的资料, 我发现linux线程
默认结束之后, 线程的资源不会得到释放。
Linux系统中程序的线程资源是有限的,表现为对于一个程序其能同时运行的线程数是有限的。
而默认的条件下,一个线程结束后,其对应的资源不会被释放,于是,如果在一个程序中,
反复建立线程,而线程又默认的退出,则最终线程资源耗尽,进程将不再能建立新的线程。
释放线程资源的两种方法:
第一种:是系统在线程结束之后自动释放资源
pthread_t pThread; //创建线程
pthread_attr_t pProprety; //线程属性
pthread_attr_init(&pProprety); //初始化线程属性
pthread_attr_setdetachstate(&pProprety,PTHREAD_CREATE_DETACHED); //设置线程属性
pthread_create(&pThread, &pProprety,(void *)init_convert,client_sock);//创建线程时将线程属性传进去
这样编码,线程结束后,内存会被释放掉。
第二种:把分离的操作放在线程中
void clear_mac(struct thread_parameter *para)
{
int portid = 0;
/*将自己分离出来,便于资源的自动回收。*/
pthread_detach(pthread_self()); /*把分离的操作放在线程中*/
if (para->port_index == 0) {
/*clear_mac_by_vlan(skfd,para.vlan_id)*/
for(portid = 1; portid <= PNUM; portid++)
clear_mac_by_port(skfd, portid);
}
else if (para->type == LT_FLASH_ONLY_THE_PORT) {
clear_mac_by_port(skfd, para->port_index);
}
else if (para->type == LT_FLASH_ALL_PORTS_EXCLUDE_THIS) {
/* why should clear all ports? do more no harm! */
for(portid = 1; portid <= PNUM; portid++)
if(portid != para->port_index)
clear_mac_by_port(skfd, portid);
}
//pthread_exit(0);
}
这样编码,线程结束后,内存会被释放掉。
第三种:是用别的线程或者进程释放此线程的资源。线程或者进程中调用pthread_join()。
pthread_t t;
pthread_create( NULL, NULL, GetSub, (void*)lp);
pthread_join( t);
值得注意的是,pthread_join(t)是阻塞的函数。如果t线程不消亡,这个线程就会一直在这里等待,直到t线程消亡。
减少自动分配的栈空间
参考链接:线程栈大小设置pthread_attr_setstacksize()
#include <iostream>
#include <limits.h>
#include <pthread.h>
#include "error.h"
using namespace std;
int main(){
pthread_t thread;
size_t stacksize;
pthread_attr_t thread_attr;
int ret;
pthread_attr_init(&thread_attr);
int new_size = 20480;
ret = pthread_attr_getstacksize(&thread_attr,&stacksize);
if(ret != 0){
cout << "emError" << endl;
return -1;
}
cout << "stacksize=" << stacksize << endl;
cout << PTHREAD_STACK_MIN << endl;
ret = pthread_attr_setstacksize(&thread_attr,new_size);
if(ret != 0)
return -1;
ret = pthread_attr_getstacksize(&thread_attr,&stacksize);
if(ret != 0){
cout << "emError" << endl;
return -1;
}
cout << "after set stacksize=" << stacksize << endl;
ret = pthread_attr_destroy(&thread_attr);
if(ret != 0)
return -1;
return 0;
}