views:

98

answers:

2

Hello.

When you create a TThread descendant using the tool palette in your BDS, you can provide a name for the thread. Here's the auto-generated code. You just call the SetName() function in the Execute method and the thread calling this method is given a name in a kind of weird way...

{$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;

I find it really useful during debugging for you can see not only TIDs, but also thread names assigned that way. You know which thread is which thanks to that.

Please tell me, however, if the name assigned can be accessed in any way. Can it be read based on a thread's handle? Or can it be read even from 'outside' the process by another process? You know, there are applications which list your processes and the threads working in them. Will this name be accessible to apps like that?

Thanks!

+6  A: 

It's entirely a debugging feature. In fact, the thread object doesn't even keep track of its own name. It sends it directly to the debugger, but doesn't store a copy of the name for itself. It's not accessible from within your own program or from anywhere else, except the debugger.

Rob Kennedy
+8  A: 

Actually, thread names are just used for debugging purposes and nothing else, really. In your code, you could just identify threads by using the ThreadID. And if you want to keep a name with those thread ID's, keep a separate (dictionary) list which maps each thread ID to whatever name you like.
The hack that you see does a nasty trick. The exception that is raised is captured by the debugger, which just handles it as a special exception and will just continue execution. The exception flag just tells the system to continue after the exception is raised, since the code will handle it. The empty except-clause is handling the exception within your code. It's just a dirty trick to communicate with the debugger, which will zee the exception and remember the name you've just passed to it...

Workshop Alex
Thanks for a clear explanation. So is there another way to assign a name to a thread so I can see it from outside? I guess there is not, but I just want to make sure :). Thanks
Mariusz
Actually, threads are nameless. But to assign a name to them, use a dynamic array with two values per element: one for ID, one for the name. In .NET, there's a dictionary class. In Delphi, you'd have to write something similar yourself.
Workshop Alex
Then again, that 'dictionary' you'd write should then be callable somehow from outside. It's not an easy task, although it is technically possible. Question is, it is a feature valuable enough to include in your code?
Workshop Alex
OK, thanks. I think I know how to do that, but it is not as important for me. I just wanted to know if naming thread is possible. Thanks for your help!
Mariusz