线程(pthread)耗内存问题解决

线程耗内存问题解决

问题提出

为了解决其它的问题,不得不加一个线程,程序不卡在那里,之前加了一个线程实际测试发现占用了
非常多的内存。

解决:

多线程内存占用分析

参考链接: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;
}
  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值