Descendant of TThread, accessing properties from main thread - multithreading

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?

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).

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.

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.

Related

delphi - class static method, static var in multi thread application

I relative new with delphi XE2, I want to know about something, if I have like this code
TSomeClass=class
strict private
class var
FCounter:integer;
public
class procedure SomeProcedure();static
end;
implementation
class procedure SomeProcedure()
begin
inc(FCounter);
end;
initialization
begin
FCounter:=0;
end;
finalization
begin
FCounter:=0;
end;
As my understanding, SomeProcedure() will static on memory, and single instance,
my question
if TSomeClass accessed by many thread, TSomeClass thread-safe or not? or it will make overlapping between thread?
if yes, do I need critical section for each thread? or another approach for that kind of method...
if two different thread accessed this method, how about FCounter? FCounter will count sequential from last value or different thread with different value start from zero?
There is no synchronization between different invocations of methods. If the methods, no matter what type of methods they are, access shared data, then synchronization may be needed.
It does not make any difference if they method is a class method or an instance method, static or dynamic, etc. All that matters is whether or not there are shared objects being accessed from multiple threads.
If two different thread accessed this method, how about
FCounter? FCounter will count sequential from last value
or different thread with different value start from zero?
In your code, FCounter is a class variable. There is a single instance of the variable, shared between all threads. A class variable is just a global variable, nothing more, nothing less.
Your code modifies that shared variable. As written the code has a data race. You can solve it with synchronization. For example by using InterlockedIncrement rather than inc.
class procedure SomeProcedure;
begin
InterlockedIncrement(FCounter);
end;
For more complex objects you'd serialize with a critical section.
Your class is not thread safe.
The easiest way to get the counter thread safe is to use TInterlocked.Increment(FCounter) instead of Inc(FCounter). All TInterlocked methods are executed as atomic operations, the same applies for the Windows API function InterlockedIncrement() which could be used here as well.

Is synchronization needed inside FinalConstruct()/FinalRelease()?

In my free-threaded in-proc COM object using ATL I want to add a member variable that will be set only in FinalConstruct() and read only in FinalRelease(). No other code will ever manipulate that member variable.
I doubt whether I need synchronization when accessing that member variable. I carefully read ATL sources and looks like those methods are always called no more than once and therefore from one thread only.
Is that correct assumption? Can I omit synchronization?
Yes, the assumption is correct. Think of it as an extension of the C++ constructor and destructor. In theory, you could call a method on a COM object from a different thread, while FinalRelease() is executing. Although, that is undefined behaviour, and not an expected occurrence. You shouldn't try to protect yourself from it, just as you wouldn't try to protect yourself from other threads in a destructor. If you have to protect yourself in the destructor, the design is generally broken (it would indicate that you do not have a proper termination protocol between your threads).
The only way FinalRelease() could be called from another thread, is when the client code does not have a valid reference count to your object, or if some other parts of your code is releasing twice. This is a hard error, and will probably end up in a crash anyway, totally unrelated to any synchronization errors you might have. The ATL code for managing object reference count is thread safe, and will not leave any race conditions open.
As for FinalConstruct(), a reference to the object is not returned to any client before FinalConstruct() has finished with a successful return code.

Class instances "owning" TMultiReadExclusiveWriteSynchronizer instances?

I have a multi-threaded Delphi program creating multiple instance of some classes, and I want each class instance to have its own instance of TMultiReadExclusiveWriteSynchronizer for use in the get and set methods of specific properties.
E.g. Here's part of a unit where I'm using a TMultiReadExclusiveWriteSynchronizer in one class:
interface
TSGThread=class(TThread)
private
fWaiting:boolean;
function getWaiting:boolean;
procedure setWaiting(value:boolean);
public
property waiting:boolean read getWaiting write setWaiting;
end;
implementation
var syncWaiting:TMultiReadExclusiveWriteSynchronizer;
function TSGThread.getWaiting:boolean;
begin
syncWaiting.BeginRead;
result:=fWaiting;
syncWaiting.EndRead;
end;
procedure TSGThread.setWaiting(value:boolean);
begin
syncWaiting.BeginWrite;
fWaiting:=value;
syncWaiting.EndWrite;
end;
initialization
syncWaiting:=TMultiReadExclusiveWriteSynchronizer.Create;
finalization
syncWaiting.Free;
end.
The problem with this is that the unit creates one instance of TMultiReadExclusiveWriteSynchronizer which is then used by multiple instances of TSGThread.
The synchronizer is only controlling access to a private field of TSGThread.
Thread A could modify the field in Thread B using the public property, hence the need for the synchronizer, but there should be a separate synchronizer in each thread so the threads don't have to wait on each other if they're modifying their own properties.
Delphi Help says "create a global instance of TMultiReadExclusiveWriteSynchronizer", but is it strictly necessary for it to always be global?
If a class is only protecting access to its own properties, will the synchronization work with a TMultiReadExclusiveWriteSynchronizer instance in a private field?
The help says this:
Create a global instance of TMultiReadExclusiveWriteSynchronizer that is associated with the global memory you want to protect.
But you don't have global memory. You have thread-object-specific memory, so create synchronization objects for each thread object. You can create as many as you need. Create one for each shared element you wish to individually access and protect.
This is a little bit off-topic, but in the example you give, the synchronizer is pretty much useless. A boolean cannot be partially read/written on a thread context switch.
Also, with your example, code like this
sgThread.Waiting := not sgThread.Waiting;
could fail.
Now, back to the topic. TMultiReadExclusiveWriteSynchronizer's scope needs to be as large as the resource it protects. Since you want to protect a private field of an object, you can declare the TMultiReadExclusiveWriteSynchronizer as a private field as well. (You are protecting access to the private field, not the access to the property)
It's not strictly necessary for it to be global. It is necessary for the every access to go through the synchronizer in order to maintain thread safety. One easy way to enable that is by making the synchronizer a global variable, but there are other ways to handle it.

are class level property or variables thread safe

I always had this specific scenario worry me for eons. Let's say my class looks like this
public class Person {
public Address Address{get;set;}
public string someMethod()
{}
}
My question is, I was told by my fellow developers that the Address propery of type Address, is not thread safe.
From a web request perspective, every request is run on a separate thread and every time
the thread processes the following line in my business object or code behind, example
var p = new Person();
it creates a new instance of Person object on heap and so the instance is accessed by the requesting thread, unless and otherwise I spawn multiple threads in my application.
If I am wrong, please explain to me why I am wrong and why the public property (Address) is not thread safe?
Any help will be much appreciated.
Thanks.
If the reference to your Person instance is shared among multiple threads then multiple threads could potentially change Address causing a race condition. However unless you are holding that reference in a static field or in Session (some sort of globally accessible place) then you don't have anything to be worried about.
If you are creating references to objects in your code like you have show above (var p = new Person();) then you are perfectly thread safe as other threads will not be able to access the reference to these objects without resorting to nasty and malicious tricks.
Your property is not thread safe, because you have no locking to prevent multiple writes to the property stepping on each others toes.
However, in your scenario where you are not sharing an instance of your class between multiple threads, the property doesn't need to be thread safe.
Objects that are shared between multiple threads, where each thread can change the state of the object, then all state changes need to be protected so that only one thread at a time can modify the object.
You should be fine with this, however there are a few things I'd worry about...
If your Person object was to be modified or held some disposable resources, you could potentially find that one of the threads will be unable to read this variable. To prevent this, you will need to lock the object before read/writing it to ensure it won't be trampled on by other threads. The easiest way is by using the lock{} construct.

Delphi threading - which parts of code need to be protected/synchronized?

so far I thought that any operation done on "shared" object (common for multiple threads) must be protected with "synchronize", no matter what. Apparently, I was wrong - in the code I'm studying recently there are plenty of classes (thread-safe ones, as the Author claims) and only one of them uses Critical Section for almost every method.
How do I find what parts / methods of my code needs to be protected with CriticalSection (or any other method) and which not?
So far I haven't stumbled upon any interesting explanation / article / blog note, all google results are:
a) examples of synchronization between thread and the GUI. From simple progressbar to most complex, but still the lesson is obvious: each time you access / modify the property of GUI component, do that in "Synchronize". But nothing more.
b) articles explaining Critical Sections, Mutexes etc. Just a different approaches of protection/synchronization.
c) Examples of very very simple thread-safe classes (thread safe stack or list) - they all do the same - implement lock / unlock methods which do enter/leave critical section and return the actual stack/list pointer on locking.
Now I'm looking for explanation which parts of code should be protected.
could be in form of code ;) but please don't provide me with one more "using Synchronize to update progressbar" ... ;)
thank you!
You are asking for specific answers to a very general question.
Basically, apart of UI operations, you should protect every shared memory/resource access to avoid two potentially competing threads to:
read inconsistent memory
write memory at the same time
try to use the same resource at the same time from more than one thread... until the resource is thread-safe.
Generally, I consider any other operation thread safe, including operations that access not shared memory or not shared objects.
For example, consider this object:
type
TThrdExample = class
private
FValue: Integer;
public
procedure Inc;
procedure Dec;
function Value: Integer;
procedure ThreadInc;
procedure ThreadDec;
function ThreadValue: Integer;
end;
ThreadVar
ThreadValue: Integer;
Inc, Dec and Value are methods which operate over FValue field. The methods are not thread safe until you protect them with some synchronization mechanism. It can be a MultipleReaderExclusiveWriterSinchronizer for Value function and CriticalSection for Inc and Dec methods.
ThreadInc and ThreadDec methods operate over ThreadValue variable, which is defined as ThreadVar, so I consider it ThreadSafe because the memory they access is not shared between threads... each call from different thread will access different memory address.
If you know that, by design, a class should be used only in one thread or inside other synchronization mechanisms, you're free to consider that thread safe by design.
If you want more specific answers, I suggest you try with a more specific question.
Best regards.
EDIT: Maybe someone say the integer fields is a bad example because you can consider integer operations atomic on Intel/Windows thus is not needed to protect it... but I hope you get the idea.
You misunderstood TThread.Synchronize method.
TThread.Synchronize and TThread.Queue methods executes protected code in the context of main (GUI) thread. That is why you should use Syncronize or Queue to update GUI controls (like progressbar) - normally only main thread should access GUI controls.
Critical Sections are different - the protected code is executed in the context of the thread that acquired critical section, and no other thread is permitted to acquire the critical section until the former thread releases it.
You use critical section in case there's a need for a certain set of objects to be updated atomically. This means, they must at all times be either already updated completely or not yet updated at all. They must never be accessible in a transitional state.
For example, with a simple integer reading/writing this is not the case. The operation of reading integer as well as the operation of writing it are atomic already: you cannot read integer in the middle of processor writing it, half-updated. It's either old value or new value, always.
But if you want to increment the integer atomically, you have not one, but three operations you have to do at once: read the old value into processor's cache, increment it, and write it back to memory. Each operation is atomic, but the three of them together are not.
One thread might read the old value (say, 200), increment it by 5 in cache, and at the same time another thread might read the value too (still 200). Then the first thread writes back 205, while the second thread increments its cached value of 200 to 203 and writes back 203, overwriting 205. The result of two increments (+5 and +3) should be 208, but it's 203 due to non-atomicity of operations.
So, you use critical sections when:
A variable, set of variables, or any resource is used from several threads and needs to be updated atomically.
It's not atomic by itself (for example, calling a function which is guarded by critical section inside of the function body, is an atomic operation already)
Have a read of this documentation
http://www.eonclash.com/Tutorials/Multithreading/MartinHarvey1.1/ToC.html
If you use messaging to communicate between threads then you can basically ignore synchronisation primitives completely because each thread only accesses its internal structures and the messages themselves. In essence this is far easier and more scalable architecture than using synchronisation primitives.

Resources