More common would be variables declared in the Class Module scope that would be implicit STATIC. Access to then would not be Thread Safe.
Not an issue if they are defined THREAD. That’s the easy fix, but that is a different animal that may not work as desired.
A Critical Section is something that may be defined in Class Module scope to be Static and shared by all instances. Clarion Sync makes that easy to declare as a Class. The Win API way it is a Group that requires a call to Init.
A CLASS can be defined with THREAD. It fires the CONSTRUCT for each new Thread started, in that you could init variables. All variables are Thread.
An interesting topic is “One-Time Initialization”.
You have something like a class module CS that needs to be initialized once. The easy way is to always init it when the program starts using a constructor. But you may never use the Class, so it seems wasteful to init. You could have many classes initing many CS that may never be actually used.
So you want to wait until the first time the class is used to init. You should protect against a possible race condition if 2 threads are using the class and discover the init needs to be done.
One way is to create the CS using a local variable, then use an Interlocked function to assign it to the module variable. The other way is to have yet another Sync object for creating CS.
The point of my mention of this is Windows Vista added a new API for One-Time Initialization to be Thread Safe. I’ve have not used it…yet.
It’s that you may not use it every time the program runs, like Check for Update.
A program may be large with many features / classes. Each Class with a Critical Section will need to initialized it one time. Ideally you want to wait to do that One-Time Init to when that class is used the first time.
Critical Sections are quite expensive. The Clarion RTL almost always uses more simple and fast synchronization based on analog of the API’s InterlockedExchange function. More complex synchronization objects (semaphores, mutexes) are using only where a simple solution is not enough.
“Critical Sections are quite expensive.”
I have understood from the clarion docs that critical sections were the simplest (fastest) synchronization objects.
Interlock exchange provides atomic operations for variables shared by multiple threads, but can be used for serialized access to some code ??
Also, I think that you can declare constants as STATIC (without THREAD) and they are thread safe (por example strings).
I was not exact. Critical sections are relatively more expensive and less flexible than synchronization objects based on InterlockedExchange or InterlockedCompareExchange. And they do not allow thread yielding while they are in the wait state.
Yes, if to look at this function (and at InterlockedCompareExchange) more mindfully…