使用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,还可以看到以这种方式分配的线程名称。你知道哪个线程是由于这个。
但是,请告诉我,是否可以以任何方式访问分配的名称。可以根据线程的句柄读取吗?或者甚至可以通过另一个过程从“外部”读取它?您知道,有些应用程序会列出您的进程以及在其中工作的线程。这样的应用程序是否可以访问此名称?
谢谢!
答案 0 :(得分:9)
实际上,线程名称仅用于调试目的,而不是其他任何内容。在您的代码中,您可以使用ThreadID识别线程。如果你想保留这些线程ID的名称,请保留一个单独的(字典)列表,将每个线程ID映射到你喜欢的任何名称。
你看到的黑客做了一个讨厌的伎俩。引发的异常由调试器捕获,调试器将其作为特殊异常处理,并将继续执行。异常标志只是告诉系统在引发异常后继续,因为代码将处理它。空的except子句是在代码中处理异常。与调试器进行通信只是一个肮脏的技巧,它会触发异常,并记住你刚刚传递给它的名字......
答案 1 :(得分:6)
这完全是一个调试功能。实际上,线程对象甚至不跟踪自己的名称。它将其直接发送到调试器,但不会为自己存储名称的副本。除了调试器之外,它无法从您自己的程序或其他任何地方访问。