每个线程都有一个堆栈。

来源:互联网 发布:mac 文件夹 突然消失 编辑:程序博客网 时间:2024/04/28 12:01

每个线程都有一个堆栈。

MSDN:

The default size for the reserved and initially committed stack memory is specified in the executable file header. Thread or fiber creation fails if there is not enough memory to reserve or commit the number of bytes requested. To specify a different default stack size for all threads and fibers, use the STACKSIZE statement in the module definition (.def) file. For more information on these default sizes and how to change them, see the documentation included with your linker.

Generally, the reserve size is the default reserve size specified in the executable header. However,if the initially committed size specified by dwStackSize is larger than the default reserve size, the reserve size is this new commit size rounded up to the nearest multiple of 1 MB.

To change the reserved stack size, set the dwCreationFlags parameter of CreateThread or CreateRemoteThread to STACK_SIZE_PARAM_IS_A_RESERVATION and use the dwStackSize parameter. 

-------------------------------------------------------------
STACK_SIZE_PARAM_IS_A_RESERVATION
0x00010000

The dwStackSize parameter specifies the initial reserve size of the stack. If this flag is not specified, dwStackSize specifies the commit size.

--------------------------------------------------------------

我用MSDN2001版查看的时候,它有注明STACK_SIZE_PARAM_IS_A_RESERVATION 适用于XP系统, 在MSDN2008版没注明了,我是在XP下测试的

下面是我改的测试代码:

 

复制代码
代码
 1 #include "stdafx.h"
 2 #include <stdio.h>
 3 #include <windows.h>
 4 
 5 #define STACK_SIZE 64*1024 // 设置线程栈为64K
 6 
 7 DWORD WINAPI ThreadFunc(PVOID pvParam)
 8 {
 9     DWORD dwRet = 0;
10     printf("%-3d:0x%x\n",pvParam,&dwRet);
11     Sleep(2000);  // 避免线程退出,这个线程栈地址又被分配给其它新创建的线程
12     return dwRet;
13 }
14 
15 int main(int,char**)
16 {
17     DWORD dwTid;
18     printf("Main:0x%x\n",&dwTid);
19 
20     HANDLE handles[10];
21 
22     for(int i=0;i<10;i++)
23     {
24         handles[i] = CreateThread(NULL,STACK_SIZE,ThreadFunc,(PVOID)i,STACK_SIZE_PARAM_IS_A_RESERVATION ,&dwTid);
25         Sleep(100); // 保证每次Create后得到的线程栈地址是递增的
26     }
27     for(int i=0; i<10; i++)
28     {
29         CloseHandle(handles[i]);
30     }
31 
32     getchar();
33     return 0;
34 }
复制代码

   -----CreateThread(NULL,STACK_SIZE,ThreadFunc,(PVOID)i,STACK_SIZE_PARAM_IS_A_RESERVATION ,&dwTid);

运行结果:

 

 每次相差(10000)x = (655366)d = 64*1024, 设置成功,64K.

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

转自:http://www.cnblogs.com/nsnow/archive/2010/08/06/1794490.html

//---------------------------------------------------------------------------------------------------------

Each new thread or fiber receives its own stack space consisting of both reserved and initially committed memory. The reserved memory size represents the total stack allocation in virtual memory. As such, the reserved size is limited to the virtual address range. The initially committed pages do not utilize physical memory until they are referenced; however, they do remove pages from the system total commit limit, which is the size of the page file plus the size of the physical memory. The system commits additional pages from the reserved stack memory as they are needed, until either the stack reaches the reserved size minus one page (which is used as a guard page to prevent stack overflow) or the system is so low on memory that the operation fails.

It is best to choose as small a stack size as possible and commit the stack that is needed for the thread or fiber to run reliably. Every page that is reserved for the stack cannot be used for any other purpose.

A stack is freed when its thread exits. It is not freed if the thread is terminated by another thread.

The default size for the reserved and initially committed stack memory is specified in the executable file header. Thread or fiber creation fails if there is not enough memory to reserve or commit the number of bytes requested. The default stack reservation size used by the linker is 1 MB. To specify a different default stack reservation size for all threads and fibers, use the STACKSIZE statement in the module definition (.def) file. The operating system rounds up the specified size to the nearest multiple of the system's allocation granularity (typically 64 KB). To retrieve the allocation granularity of the current system, use the GetSystemInfo function.


To change the initially committed stack space, use the dwStackSize parameter of the CreateThread, CreateRemoteThread, or CreateFiber function. This value is rounded up to the nearest page. Generally, the reserve size is the default reserve size specified in the executable header. However, if the initially committed size specified by dwStackSize is larger than or equal to the default reserve size, the reserve size is this new commit size rounded up to the nearest multiple of 1 MB.

To change the reserved stack size, set the dwCreationFlags parameter of CreateThread or CreateRemoteThread to STACK_SIZE_PARAM_IS_A_RESERVATION and use the dwStackSize parameter. In this case, the initially committed size is the default size specified in the executable header. For fibers, use the dwStackReserveSize parameter of CreateFiberEx. The committed size is specified in the dwStackCommitSize parameter.

大概意思:线程栈空间默认是1M,手动配置该值时(通过/STACK开关或者def文件的STACK指令),系统实际分配的栈大小是该值向上舍入到最近的整数倍栈粒度(一般是64K,可调用GetSystemInfo查询)大小,比如在/STACK中手动配置值为65K,系统则会分配128K(=2 * 64K)的栈空间。


CreateThread函数中的dwStackSize参数并不是为新线程指定的栈空间大小,它是初次提交给线程栈空间的页面大小,系统实际提交的大小是该值向上舍入到最近的页面文件大小整数倍大小,比如指定dwStackSize为13K时,由于页面文件一般为4K,因此系统将实际提交4*4 = 16K的页面文件。

如果dwStackSize大于/STACK的指定值或默认值1M,系统将调整线程栈大小,使其变为dwStackSize向上舍入且距离dwStackSize最近的1M的整数倍。比如dwStackSize设置为2049K,且/STACK保持默认值1M,则系统将线程栈空间调整为3M。