设置线程堆栈大小-----一台电脑最多能开启多少个线程

来源:互联网 发布:nginx 录播保存record 编辑:程序博客网 时间:2024/05/02 04:59
//http://www.cnblogs.com/nsnow/archive/2010/08/06/1794490.html
//http://blog.csdn.net/nokianasty/article/details/7600322


// Linux平台的栈默认大小应该是8192KB, Windows平台的栈默认大小应该是1024KB, 项目移植的时候要注意设置, 免得空间不足, 分配失败


#include <process.h>
#include <Windows.h>
#include <iostream>
using namespace std;


class CTest
{
private:
int *m_a;
public:
CTest(){m_a=new int;cout<<"CTest()"<<endl;}
~CTest(){if(m_a!=NULL){delete m_a;m_a=NULL;cout<<"~CTest()"<<endl;}}
};
//以下是_beginthreadex的函数原型
/*_CRTIMP uintptr_t __cdecl _beginthreadex
(_In_opt_ void * _Security, 
_In_ unsigned _StackSize,
_In_ unsigned (__stdcall * _StartAddress) (void *), 
_In_opt_ void * _ArgList, 
_In_ unsigned _InitFlag, 
_Out_opt_ unsigned * _ThrdAddr);
*/
//1--------当_StackSize为0时(_InitFlag=0),即默认时,线程栈大小为1M(1024*1024)
//2--------当_StackSize>1M时(_InitFlag=0或_InitFlag=STACK_SIZE_PARAM_IS_A_RESERVATION),线程栈大小都为设定堆栈大小
//3--------当_StackSize<1M时(_InitFlag=0),线程栈大小为1M
//4--------当_StackSize<1M时(_InitFlag=STACK_SIZE_PARAM_IS_A_RESERVATION),线程栈大小为设定堆栈大小
//5--------当设定栈大小为20M时,总共内存使用应该是20*5+进程内存>100M,但用任务管理器查看此程序内存使用情况为:1964K,即不到2M,
//---------后来知道,栈内存是线程自己管理的,不会计入进程所占内存------堆属于进程这个容器!栈属于线程这个运行单元!
#define STACK_SIZE   1024*1024*20     


UINT threadProc(void *data)
{
CTest test;
//while(true)
{
int a=1;
cout<<"线程--------"<<(int)data<<":"<<&a<<endl;
Sleep(3000);  // 避免线程退出,这个线程栈地址又被分配给其它新创建的线程(不用此句,&a地址一样,因为下一个线程使用了上一个退出线程的堆栈...)
}
_endthreadex(0);    //测试调用提前退出时是否未调用test的析构函数,等待3秒查看结果!!结果表明,_endthreadex强制提前退出线程时未调用析构函数,导致内存泄露!!!
return 0;
}


int main()
{
HANDLE handle[5]={0};
for(int i=0;i<5;i++)
{
handle[i]=(HANDLE)_beginthreadex(NULL,STACK_SIZE,(UINT(__stdcall*)(void*))threadProc,(void*)(i+1),STACK_SIZE_PARAM_IS_A_RESERVATION/*0*/,NULL);
Sleep(200);         //没有用锁,所以暂时用sleep的方式保证线程是以i依次递增的
}


for(int i=0;i<5;i++)
{
if(handle[i]!=NULL)
CloseHandle(handle[i]);
}
system("pause");
return 0;
}




02C1FF4C-0181FF4C=01400000=20M

当然这么小的程序没必要设这么大的栈,浪费大量内存资源...

同时附加测试可以看到3秒过后,只调用了构造函数,未调用析构函数,导致内存泄露,而屏蔽掉_endthreadex(0); 后则可成功调用析构函数,因此

使用_endthreadex等类似函数时应注意



依据以上结果,我们可以推断:

当默认情况时,栈大小为1M,若一台2G内存的电脑,则最多可以分配线程数应 小于  2G/1M=2048

不同内存,不同栈大小则以此类推

0 0
原创粉丝点击