views:

219

answers:

3

I have a class which is a descendant of TThread. I have some public properties that are read only. Will I run into problems if my main thread reads those values while the thread is active?

+8  A: 

If by "read-only properties" you mean the TThread descendant itself doesn't ever change them either, and initializes them a.s.a.p, then no, everything will be fine (as long as you make sure the thread is alive and kicking whenever you request the property values).

If by "read-only properties" you mean the TThread descendant will be the only one changing them, you will want to make sure the main thread isn't reading them while they are being changed (unless they are atomic values, like integers).

Paul-Jan
Perfect answer! Exactly the information I needed. I am updating the values from inside the TThread descendant and not all values are atomic. Thank you for your answer.
Majin Magu
and even "atomic" values like integers can fail if your code is not 32-bit aligned.
Lieven
Indy includes some atomic data types in Core\IdThreadSafe.pas, including IdThreadSafeInt64 and even TIdThreadSafeBoolean
mjustin
Updating "a.s.a.p." isn't enough. There's basically only one way to do this in a safe way - while the method doing the initialization is executed in the context of the main thread, i.e. in the constructor. As soon as multiple threads could be accessing the fields it is no longer safe.
mghie
@mghie: Very true, I should have been more specific there. As an alternative, you can have the TThread "createSuspended", and trigger some initilization from the main thread before resuming it. Not as nice, but I've seen it happen in certain scenarios.
Paul-Jan
@Lieven: Out of interest, in what situation would your properties not be 32-bit aligned in Delphi? Are we talking records (packed or with alignment turned off)?
Paul-Jan
+3  A: 

The basic types, like Integer, Boolean, Char, and Pointer, are safe to read at any time. Reference types, like string, interfaces, and dynamic arrays, are safe to read only if there's no chance the other thread could be assigning a new value at the same time. Use a critical section or the Synchronized method, for example, to make sure the thread isn't modifying the value while the main thread is reading from it.

You also have to remember that any value you read may be out of date by the time you use it — the thread might have written a new value between the time you read it and the time you use it.

Rob Kennedy
I believe it's called "Synchronize" (no D at the end)
Mason Wheeler
+2  A: 

That depends on the property types and possibly on their accessor methods.

type
  TMyThread = class(TThread)
  private
    FIntfield: integer;
  public
    property IntField: integer read FIntField;
  end;

Accessing this property won't be a problem since accessing 32 bit values is an atomic operation. But if the property is larger than 32 bit or a class reference that might be changed while the main thread accesses it, you will run into trouble.

dummzeuch