线程堆栈

线程堆栈大小http://blog.csdn.net/nokianasty/article/details/7600321

C++内存分布http://blog.csdn.net/morewindows/article/details/6851681

线程堆栈分布http://bbs.csdn.net/topics/390391357

在看了这三篇的讨论后,对于线程堆栈,内存分布等有了一点了解,以上引出几篇文章,再做一些自己的总结:

首先,引出这方面问题是因为多线程编程中,过多的线程导致存储不足的情况,猜测占用了许多空闲的内存,于是探究一些解决方法。

1).线程分为内核态与用户态。

首先是内核,指的是操作系统中最基础的一些部分,提供一些分装的结构,方法,对外部限制访问权限。即对于用户是一个只知道接口,不知道内部的结构。

内核态线程,即对内核可见线程,有比较小的数据堆栈,易于调度,调度依赖于操作系统,一个线程阻塞,操作系统依据自己的策略调度其他可用线程,实现线程的并发。

用户态线程,对于内核不可加,一个线程阻塞时,如果用户不手动调度,整个进程都会阻塞。

由于在项目中用CreateThread创建的线程已经是内核态的线程,故这里没有改进。

 

2).存储变量分为五个区,堆,栈,自由区,全局/静态区,常量区。

摘自以上某篇文章的示意图如下:

其中new []使用的是堆,全进程共享,查了一些资料,说堆最大为2GB。;malloc,局部变量,函数调用时的参数传递会用到栈,如int *a=int[n]。

通常,每个线程一个栈,每个进程一个堆。所以线程数目的瓶颈在于线程自己的堆栈。这里的堆栈仅仅指的是栈。Visual C++编译器默认设置是每个线程的堆栈大小是1MB。

32位的计算机,地址内存空间为2^32,即4G,其中2G分配给用户使用,给自己创建的线程分配的是虚拟内存。

一般当线程数为2000*1MB=2G时,会超过一般的限制,报错。相应的64就最多8000个线程。

当然,如果在创建线程时指定较小的堆栈大小,就应该可以创建较多的线程。

 

查看项目代码中buffer的代码段,如下:

m_p = new C* [Size];
for (int i = 0; i < Size; ++ i)
m_p[i] = NULL;

也就是说,这里的缓冲区空间大部分用new 来创建,也就是放在进程共享的堆区,而不是线程的栈区,我们也就能够通过修改每个线程的栈的大小来减少空间。

在VS2010下设置有两个入口:

A.项目配置

B.CreateThread调用时的第二个参数;

运行时取其中较大的一个。

于是,解决方法其中之一可以为修改线程栈大小。

 

3).然后又接触到了一个概念:线程池,查找相关的博客http://blog.csdn.net/conceptcon/article/details/9268573

这篇博客比较详细地介绍了线程池的概念,自己归纳总结如下:

诸如服务器端,有时候要起许多处理短任务的线程,即线程实际执行的时间比线程创建和销毁的时间长不了多少,这时候优化线程的创建销毁就成了一个问题。

于是引进线程池的概念,简单地说就是创建两个线程队列,一个空余线程队列,一个忙碌线程队列,来了任务,分配工作给空闲线程的第一个线程,并把这个线程转入到忙碌队列中,这样就实现了线程的共享机制。不过项目中执行的任务是文件传输型的,一般来说线程处理的时间要远远大于线程创建和销毁时间,所以如果引入线程池,应该没有多大的改进效果,所以暂时不考虑线程池。

 

这里对上述做一个总结,本文探讨三个方法,内核态线程,减少线程栈大小,使用线程池。根据不同的情况,可采用不同的策略来进行线程空间优化。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值