线程堆栈的理解
2014-02-17 17:19
169 查看
一个线程的开销包括:
内核模式下的开销(内核堆栈,对象管理所需内存)
用户模式下的开销(线程局部存储、线程环境块、堆栈、CRT、MFC、COM等等等等)
通常,线程数目的瓶颈在于线程自己的堆栈。Visual C++编译器默认设置是每个线程的堆栈大小是1MB。当然,如果你在创建线程时指定较小的堆栈大小,你应该可以创建较多的线程。
但是创建大量线程不是一个好的设计。每个线程创建和销毁的时候,Windows会调用已经加载的动态链接库的DLLMain,传递DLL_THREAD_ATTACH和DLL_THREAD_DETACH作为参数,除非动态库使用DisableThreadLibraryCalls禁用了这个通知。在创建大量线程的时候,这个开销是很大的。对于你这样的用后即弃的线程,你应该使用线程池。一个线程池示例可以在微软知识库找到。
参数和局部变量的函数都存储在线程的堆栈。 如果声明局部变量具有大型值, 堆栈快速耗尽。 例如, 在以下代码示例函数要求堆栈来存储数组 1,200,000 个字节。
void func(void) { int i[300000]; // Use 300,000 integers multiplied by 4 bytes per integer to store the array. return; }
要避免使用堆栈,使用动态分配内存。 例如, 在以下代码示例函数动态分配内存。
void func(void) { int *i i = new int[400000]; // More code goes here. return; } 在此代码示例, 内存存储在堆栈代替。 因此, 函数不需要堆栈来存储数组 1,200,000 个字节。
由此也解开了为什么我在一个进程中创建大于2000个线程时导致程序异常退出,因为每个线程的默认堆栈是1MB,2000*1MB = 2GB,my God!
可以在创建线程时指定线程堆栈大小,这样就能创建更多的线程了!但是前面提到,大量的创建线程并销毁,会带来大量的系统开销,所以尽量避免创建大量线程,推荐使用线程池,但是偶现在还不会用,快去查查!
相关文章推荐
- 线程与堆栈资源关系理解
- 线程安全和线程不安全理解
- 个人对于线程安全的理解(内容会不断更新,只是个人理解,不具备权威性)
- java线程安全理解
- 线程创建和结束理解
- 关于守护线程的理解和例子
- 从函数调用过程中的堆栈变化理解缓冲区溢出
- 【并发】1、关于线程的几种状态&关于yield的理解
- c语言中堆栈的简单理解
- 深入理解Java类加载器:线程上下文类加载器
- 进程与线程的理解
- 有关【线程】销毁的理解
- 进程、线程和协程的理解
- 线程堆栈大小 pthread_attr_setstacksize 的使用
- 达内java培训专家:如何理解Java堆栈?
- 主副线程的交互---我记录下 也许不对。同事教我的。我自己去的名字。理解问题。
- 关于JAVA线程的理解
- 获取iOS任意线程调用堆栈(四)符号化实战
- iOS 进程线程及堆栈关系的总结