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

时间:2010-10-05 13:56:02

标签: multithreading delphi

使用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;

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

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

谢谢!

2 个答案:

答案 0 :(得分:9)

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

答案 1 :(得分:6)

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