日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 >

设置线程堆栈大小

發(fā)布時(shí)間:2025/7/25 50 豆豆
生活随笔 收集整理的這篇文章主要介紹了 设置线程堆栈大小 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

每個(gè)線程都有一個(gè)堆棧那么,這個(gè)堆棧多大呢?

HANDLE CreateThread(
?????? LPSECURITY_ATTRIBUTES lpThreadAttributes,
?????? SIZE_T dwStackSize,
?????? LPTHREAD_START_ROUTINE lpStartAddress,
?????? LPVOID lpParameter,
?????? DWORD dwCreationFlags,
?????? LPDWORD lpThreadId
);

在創(chuàng)建線程的時(shí)候可以指定堆棧大 小,dwStackSize=0則使用默認(rèn)大小


-那默認(rèn)大小又是多少?

????? 寫個(gè)小程序算一下~

#include <stdio.h>
#include <windows.h>

#define STACK_SIZE 0.5*1024*1024

DWORD WINAPI ThreadFunc(PVOID pvParam)
{
????? DWORD dwRet = 0;
????? printf("%-3d:0x%x\n",pvParam,&dwRet);
????? return dwRet;
}

int
main(int,char**)
{
????? DWORD dwTid;
????? printf("Main:0x%x\n",&dwTid);
????? for(int i=0;i<50;i++)
??????? CreateThread(NULL,STACK_SIZE,ThreadFunc,(PVOID)i,0,&dwTid); // 莫小注:原作者這處代碼有錯(cuò),這不能修改線程棧大小

????? Sleep(2000);
????return 0;
}

輸出:

Main:0x12ff78
0?????? :0x50ffb0
1?????? :0x60ffb0
2?????? :0x70ffb0
3?????? :0x80ffb0
4?????? :0x90ffb0

0x60ffb0 - 0x50ffb0 = 0x100000 byte = 1MB

那么這個(gè)小程序中線程最小堆棧大小為1MB. (對(duì)么?為什么呢?后面有驗(yàn)證)
將STACK_SIZE換成0, 結(jié)果和上面一樣
將STACK_SIZE換成2, 結(jié)果變成2MB

以下是從MSDN中查到的

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.

根據(jù)winnt.h中的????? IMAGE_OPTIONAL_HEADER結(jié)構(gòu)體
typedef struct _IMAGE_OPTIONAL_HEADER {
?????? //
??????? // Standard fields.
??????? //

??????? WORD??????? Magic;
??????? BYTE??????? MajorLinkerVersion;
??????? BYTE??????? MinorLinkerVersion;
??????? DWORD?????? SizeOfCode;
??????? DWORD?????? SizeOfInitializedData;
??????? DWORD?????? SizeOfUninitializedData;
??????? DWORD?????? AddressOfEntryPoint;
??????? DWORD?????? BaseOfCode;
??????? DWORD?????? BaseOfData;

??????? //
??????? // NT additional fields.
??????? //

??????? DWORD?????? ImageBase;
??????? DWORD?????? SectionAlignment;
??????? DWORD?????? FileAlignment;
??????? WORD??????? MajorOperatingSystemVersion;
??????? WORD??????? MinorOperatingSystemVersion;
??????? WORD??????? MajorImageVersion;
??????? WORD??????? MinorImageVersion;
??????? WORD??????? MajorSubsystemVersion;
??????? WORD??????? MinorSubsystemVersion;
??????? DWORD?????? Win32VersionValue;
??????? DWORD?????? SizeOfImage;
??????? DWORD?????? SizeOfHeaders;
??????? DWORD?????? CheckSum;
??????? WORD??????? Subsystem;
??????? WORD??????? DllCharacteristics;
??????? DWORD?????? SizeOfStackReserve;
??????? DWORD?????? SizeOfStackCommit;
??????? DWORD?????? SizeOfHeapReserve;
??????? DWORD?????? SizeOfHeapCommit;
??????? DWORD?????? LoaderFlags;
??????? DWORD?????? NumberOfRvaAndSizes;
??????? IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
} IMAGE_OPTIONAL_HEADER32, *PIMAGE_OPTIONAL_HEADER32;

我推測(cè),應(yīng)該可以在鏈接期間指定棧大小
查看link.exe的參數(shù)

/STACK:reserve[,commit]
果然如此~~

看到網(wǎng)上有人問如何改變默認(rèn)的線程堆棧大小,在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.

(模塊定義 (.def) 文件為鏈接器提供有關(guān)被鏈接程序的導(dǎo)出、屬性及其他方面的信息)

可見,默認(rèn)線程堆棧大小在鏈接階段可以由程序員指定

?

?

以上部分載自他人空間.

MSDN中有段話很重要:

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.?

我用MSDN2001版查看的時(shí)候,它有注明STACK_SIZE_PARAM_IS_A_RESERVATION 適用于XP系統(tǒng), 在MSDN2008版沒注明了,我是在XP下測(cè)試的

下面是我改的測(cè)試代碼:

?

代碼 ?1?#include?"stdafx.h"
?2?#include?<stdio.h>
?3?#include?<windows.h>
?4?
?5?#define?STACK_SIZE?64*1024?//?設(shè)置線程棧為64K
?6?
?7?DWORD?WINAPI?ThreadFunc(PVOID?pvParam)
?8?{
?9?????DWORD?dwRet?=?0;
10?????printf("%-3d:0x%x\n",pvParam,&dwRet);
11?????Sleep(2000);??//?避免線程退出,這個(gè)線程棧地址又被分配給其它新創(chuàng)建的線程
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);

運(yùn)行結(jié)果:

?

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

另外,?Linux平臺(tái)的棧默認(rèn)大小應(yīng)該是8192KB, Windows平臺(tái)的棧默認(rèn)大小應(yīng)該是1024KB, 項(xiàng)目移植的時(shí)候要注意設(shè)置, 免得空間不足, 分配失敗

轉(zhuǎn)載于:https://www.cnblogs.com/nsnow/archive/2010/08/06/1794490.html

總結(jié)

以上是生活随笔為你收集整理的设置线程堆栈大小的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。