加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

delphi – 如何在TThread中设置堆栈大小?

发布时间:2020-12-15 09:48:31 所属栏目:大数据 来源:网络整理
导读:如何在TThread中设置自定义堆栈大小?我试图重新引入TThread的构造函数,但它说ThreadProc在System.Classes中缺少了它的权利. type TThreadHelper = class helper for TThread constructor Create(const CreateSuspended: Boolean = False; const StackSize:
如何在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不允许程序员指定堆栈大小,如果有人知道原因,那对我来说会非常有趣.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读