Thread safe non threaded global class object

I have a global non threaded class object

are the methods thread safe if they only use the parameters and local data to the method?

Is this thread safe?

Something like

Someclass.AddValues procedure (long a, long b)
Result long
Code
Result = a + b
Return result

Yes.

Code is thread safe.
Local variables are thread safe.
Parameters passed by value (not by *reference) are thread safe.

Properties, (aka self.whatever) are not thread safe. Other methods (that use properties) are not thread safe.

3 Likes

what Bruce said…

minor qualification - provided they are not defined as ,STATIC

1 Like

Thanks, I thought so but did not know if something unique about classes - Good heads-up with the STATIC item.

Usually when I want a STATIC I will also add THREAD so:

myLong LONG,STATIC,THREAD

that way each thread will get a separate copy.

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.

1 Like

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.

If you may never use something, then don’t add it.

1 Like

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…

1 Like

thanks for your answer. I will try Interlock exchange and associates.

Good refresher

https://clarion.help/doku.php?id=thread_model_faq.htm#q9

1 Like