Delphi中的命名线程 - 这是为了什么?

Mar*_*mke 6 delphi multithreading

使用BDS中的工具选项板创建TThread后代时,可以为该线程提供名称.这是自动生成的代码.您只需在Execute方法中调用SetName()函数,并且调用此方法的线程以一种奇怪的方式给出一个名称...

{$IFDEF MSWINDOWS}
type
  TThreadNameInfo = record
    FType: LongWord;     // must be 0x1000
    FName: PChar;        // pointer to name (in user address space)
    FThreadID: LongWord; // thread ID (-1 indicates caller thread)
    FFlags: LongWord;    // reserved for future use, must be zero
  end;
{$ENDIF}

{ TTestThread }

procedure TTestThread.SetName;
{$IFDEF MSWINDOWS}
var
  ThreadNameInfo: TThreadNameInfo;
{$ENDIF}
begin
{$IFDEF MSWINDOWS}
  ThreadNameInfo.FType := $1000;
  ThreadNameInfo.FName := 'ThreadName';
  ThreadNameInfo.FThreadID := $FFFFFFFF;
  ThreadNameInfo.FFlags := 0;

  try
    RaiseException( $406D1388, 0, sizeof(ThreadNameInfo) div sizeof(LongWord), @ThreadNameInfo );
  except
  end;
{$ENDIF}
end;
Run Code Online (Sandbox Code Playgroud)

我发现它在调试过程中非常有用,你不仅可以看到TID,还可以看到以这种方式分配的线程名称.你知道哪个线程感谢你.

但是,请告诉我,是否可以以任何方式访问分配的名称.可以根据线程的句柄读取吗?或者甚至可以通过另一个过程从"外部"读取它?您知道,有些应用程序会列出您的进程以及在其中工作的线程.这样的应用程序是否可以访问此名称?

谢谢!

Wim*_*ink 10

实际上,线程名称仅用于调试目的而不是其他任何东西.在您的代码中,您可以使用ThreadID识别线程.如果你想保留这些线程ID的名称,请保留一个单独的(字典)列表,将每个线程ID映射到你喜欢的任何名称.
你看到的黑客做了一个讨厌的伎俩.引发的异常由调试器捕获,调试器将其作为特殊异常处理,并将继续执行.异常标志只是告诉系统在引发异常后继续,因为代码将处理它.空的except子句是在代码中处理异常.与调试器进行通信只是一个肮脏的技巧,它将触发异常,并记住您刚刚传递给它的名称......


Rob*_*edy 6

这完全是一个调试功能.实际上,线程对象甚至不跟踪自己的名称.它将其直接发送到调试器,但不会为自己存储名称的副本.除了调试器之外,它无法从您自己的程序或其他任何地方访问.