如何在TThread中设置自定义堆栈大小?我试图重新引入TThread的构造函数,但它说ThreadProc在System.Classes中缺少了它的权利.
type TThreadHelper = class helper for TThread constructor Create(const CreateSuspended: Boolean = False; const StackSize: Integer = 0); reintroduce; end; { TThreadHelper } constructor TThreadHelper.Create(const CreateSuspended: Boolean; const StackSize: Integer); begin Self.FSuspended := not Self.FExternalThread; Self.FCreateSuspended := CreateSuspended and not Self.FExternalThread; if not Self.FExternalThread then begin Self.FHandle := BeginThread(nil,StackSize,@ThreadProc,Pointer(Self),CREATE_SUSPENDED,Self.FThreadID); if Self.FHandle = 0 then raise EThread.CreateResFmt(@SThreadCreateError,[SysErrorMessage(GetLastError)]); end else begin Self.FHandle := Winapi.Windows.GetCurrentThread; Self.FThreadId := GetCurrentThreadId; end; end;
[dcc32 Error] Project5.dpr(29): E2003 Undeclared identifier:
‘ThreadProc’
解决方法
我不知道,如果你可以在创建一个线程后设置堆栈大小.也许
SetThreadStackGuarantee
会对您有所帮助?
您可以使用BeginThread从头开始创建一个线程,但它非常复杂.我有一个使用Detours的解决方法.请注意,有几种Detours变体.我认为只有Cromis.Detours与x64兼容.
unit IndividualStackSizeForThread; interface uses System.Classes,Cromis.Detours { http://www.cromis.net/blog/downloads/cromis-ipc/ }; type TThreadHelper = class helper for TThread constructor Create(CreateSuspended: Boolean; StackSize: LongWord); end; implementation var TrampolineBeginThread: function(SecurityAttributes: Pointer; StackSize: LongWord; ThreadFunc: TThreadFunc; Parameter: Pointer; CreationFlags: LongWord; var ThreadId: TThreadID): THandle = nil; threadvar StackSizeOverride: LongWord; function InterceptBeginThread(SecurityAttributes: Pointer; StackSize: LongWord; ThreadFunc: TThreadFunc; Parameter: Pointer; CreationFlags: LongWord; var ThreadId: TThreadID): THandle; const STACK_SIZE_PARAM_IS_A_RESERVATION = $00010000; // http://msdn.microsoft.com/en-us/library/windows/desktop/ms682453(v=vs.85).aspx begin if StackSizeOverride <> 0 then begin CreationFlags := CreationFlags or STACK_SIZE_PARAM_IS_A_RESERVATION; StackSize := StackSizeOverride; StackSizeOverride := 0; end; Result := TrampolineBeginThread(SecurityAttributes,ThreadFunc,Parameter,CreationFlags,ThreadId); end; constructor TThreadHelper.Create(CreateSuspended: Boolean; StackSize: LongWord); begin StackSizeOverride := StackSize; inherited Create(CreateSuspended); end; initialization TrampolineBeginThread := InterceptCreate(@BeginThread,@InterceptBeginThread); finalization InterceptRemove(@TrampolineBeginThread,@InterceptBeginThread); end.
我不知道为什么Embt不允许程序员指定堆栈大小,如果有人知道原因,那对我来说会非常有趣.