How to automatically initialize / uninitialize something globally for every thread? - multithreading

I have a unit with an initialization and finalization section. This unit contains a complex object which is instantiated in the initialization and destroyed in the finalization. However, this object also contains an ADO Connection. That makes it an issue when using this across threads, because ADO is COM, and needs to be initialized for every thread.
This is how I currently handle this global object instance:
uses
ActiveX;
...
initialization
CoInitialize(nil);
_MyObject:= TMyObject.Create;
finalization
_MyObject.Free;
CoUninitialize;
end.
This only works on the main thread. Any other thread wouldn't be able to access it, and will return an exception CoInitialize has not been called.
How do I get around this to make this unit thread-safe? I would need a way to hook every creation/destruction of any thread created, and each thread would need to refer to a different instance of this object. But how to go about doing so?

Well, as you already say yourself, each thread needs to call CoInitialize separately. And in addition, each thread needs to have its own ADOConnection too.
I think you need to leave the idea of using the single global object/connection from that unit. Just repeat that object creation and destruction in each thread. When the thread types are different, then you could design a base thread class on top of them. If the object is too big (has overhead with regard to the thread) or does not 'fit' completely in the thread, then split the object design.
For now, your question sounds like just wanting to keep convenience, but if it is really necessary to centralize the ADO connection involvement, then maybe you could implement multi-cast events for the connection events of both main thread and the other threads. Logging in should not be a problem for successive connections: just store the login values and feed them to the threads.

While another design might be a better solution, you can declare _MyObject as threadvar to have a separate instance for each thread. In addition you can move the CoInitialize/CoUnitialize into the constructor/destructor of TMyObject.
I cannot give advice on when to create and free these instances as I have no idea how your threads are created and freed.

Related

Why pass parameters through thread function?

When I create a new thread in a program... in it's thread handle function, why do I pass variables that I want that thread to use through the thread function prototype as parameters (as a void pointer)? Since threads share the same memory segments (except for stack) as the main program, shouldn't I be able to just use the variables directly instead of passing parameters from main program to new thread?
Well, yes, you could use the variables directly. Maybe. Assuming that they aren't changed by some other thread before your thread starts running.
Also, a big part of passing parameters to functions (including thread functions) is to limit the amount of information the called function has to know about the outside world. If you pass the thread function everything it needs in order to do its work, then you can change the rest of the program with relative impunity and the thread will still continue to work. If, however, you force the thread to know that there is a global list of strings called MyStringList, then you can't change that global list without also affecting the thread.
Information hiding. Encapsulation. Separation of concerns. Etc.
You cannot pass parameters to a thread function in any kind of normal register/stack manner because thread functions are not called by the creating thread - they are given execution directly by the underlying OS and the API's that do this copy a fixed number of parameters, (usually only one void pointer), to the new and different stack of the new thread.
As Jim says, failure to understand this mechanism often results in disaster. There are numnerous questions on SO where the vars that devs. hope would be used by a new thread are RAII'd away before the new thread even starts.

COM object methods are not executed on the thread that CoInitialize-d and created the object

I am developing an UI application that creates a COM object along the way.
The problem is, I want to "move" this COM object entirely on a different thread.
What I do is this:
create the new thread I want to move the object into (with CreateThread API)
after entering this thread, I'm calling PeekMessage to setup a message queue for it
calling CoInitialize, CoCreateInstance to create the COM object, QueryInterface to get the interface I want
finally I call a method on the interface that displays a MessageBox with the value returned by GetCurrentThreadId() (I have access to the VB6 code of the COM library within which the object resides).
The problem is, as this message box shows, the object methods are still executed on the original UI thread, not on the thread I created and done all those steps into. One more thing to mention, after calling the interface method, I'm also setting up a classic message loop in it.
How can I change this behaviour and achieve what I want? (that is, I want the COM object calls that originate from my newly created thread to be executed ON IT, not on the original application thread)
Here's some pseudocode to make it even more clearer:
void myMainUIMethod(){
MessageBox(GetCurrentThreadId()); // displays 1
CreateThread(&myCOMObjectThreadProc);
}
void myCOMObjectThreadProc(){
MessageBox(GetCurrentThreadId()); // displays 2
CoInitialize(NULL);
myObject = CoCreateInstance(myObjectsCLSID);
myObjectInterface = myObject->QueryInterface(myObjectInterfaceCLSID);
myObjectInterface->showThreadIDMessageBox(); // this would be the COM object method call
}
And, in the VB6 code of the object, here's the pseudo-definition of showThreadIDMessageBox.
Public Sub showThreadIDMessageBox()
Call MessageBox(GetCurrentThreadId()) //displays 1, I want it to display 2
End Sub
I have achieved what I wanted by CoUninitalizing on the main thread, before creating the new thread. But why does this happen? If COM was initialized ON THE MAIN THREAD before I'm creating the new thread, maybe for some reason it had to be..I would't want the application to crash later because I had to call CoUninitialize before creating my new thread. Here's some pseudocode that illustrates that whichever thread calls CoInitialize first will be the one picked by the STA objects.
void myMainUIMethod(){
MessageBox(GetCurrentThreadId()); // displays 1
CoUninitialize(); // uninitialize COM on the main thread
CreateThread(&myCOMObjectThreadProc);
***i: MessageBox("When you want to initialize COM on main thread, confirm this");
CoInitialize();
}
void myCOMObjectThreadProc(){
MessageBox(GetCurrentThreadId()); // displays 2
***ii: MessageBox("When you want to initialize COM on the new thread, confirm this");
CoInitialize(NULL);
myObject = CoCreateInstance(myObjectsCLSID);
myObjectInterface = myObject->QueryInterface(myObjectInterfaceCLSID);
myObjectInterface->showThreadIDMessageBox(); // this shows 2 IF ***ii is confirmed before ***i, 1 otherwise
}
Thank you very much in advance,
Corneliu
Looks like your problem is that your COM component threading model is not specified in registry key InprocServer32. This means that object is considered as STA (single-threaded apartment) but will be loaded to main (or host) STA, not the STA that created it. This is the first thread that called CoInitialize. To be created in same STA that called CoCreateInstance you must create HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID\{Your CLSID}\InprocServer32#ThreadingModel registry value and set it to Apartment.
Quote from MSDN (InprocServer32 registry key documentation):
If ThreadingModel is not present or is not set to a value, the server is loaded into the first apartment that was initialized in the process. This apartment is sometimes referred to as the main single-threaded apartment (STA). If the first STA in a process is initialized by COM, rather than by an explicit call to CoInitialize or CoInitializeEx, it is called the host STA. For example, COM creates a host STA if an in-process server to be loaded requires an STA but there is currently no STA in the process.
I have finally achieved what I wanted! Adding a CoUninitialize call in the main UI thread, before creating the new thread has solved it. This happens because STA COM objects will be handled on the thread that first calls CoInitialize. Now all the calls to the objects methods are reported to be executed on the thread I created and the main window of the object (the COM component has a Form) is reported to belong to it too! (used WinSpy++ to test that).
There is still a question (and a problem) though..why does it behave this way?
Everywhere I search on the internet I see answers telling that a STA COM component will be fully executed on the thread it is created on (provided that CoInitialize or CoInitializeEx with COINIT_APARTMENTTHREADED had been called before), no matter what. Why does it matter if I called CoInitialize on another thread before..that's just plain stupid in my opinion for Microsoft to do so :), plus it might damage the future behaviour of my application, as I stated before.
EDIT: The correct answer is the one posted by Frost. Thank you again.
The threads are running in parallel and that's what they are meant to do. you need to synchronize between the two threads if you want one object to wait for some operation on other thread to complete. Event object will serve for your purpose.
You need to choose Free Threading as the Threading Model of the COM class when creating it. With C++ ATL, this is an option in the wizard when you select New -> COM class (or something like it). In .NET languages, I think this is specified as an attribute in the class.
BTW, you don't need to call QueryInterface after CoCreateInstance (unless you need more than one interface pointer). Just pass the GUID of the interface you want as the 4th parameter to CoCreateInstance.
Ah, I think I might know the problem now: it sounds like the VB6 COM object you are creating was registered as single-threaded, not apartment-threaded; this means that the object gets created on whichever thread is your app is the first to call CoInitialize().
This explain the behavior you are seeing: if you let your main thread CoInitialize() first, it becomes the "main thread" as far as COM is concerned, so the CoCreate ends up creating the object on it, even though it's CoCreated on a different thread. (This is only the case for single-threaded objects.)
But when you let your other thread CoInitialize() first, it is the "main thread" for COM, so the object gets created where you want it.
Can you change the threading model of your VB object to apartment instead of single? This would enable it to get created on the thread that calls CoCreate().
The problem is, I cannot change the threading model of the VB6 component since it is already used in other applications and it might damage it's behaviour.
...looks like that won't work for you. I guess you can check what the current threading model is, and if you can confirm that it's single, then you'll have an explanation for why it behaves the way it does, which might help you work with it.
--
So why does COM behave that way? - A: legacy compat issues. The Single Thread model is a holdover from before windows had threads in the first place, when every process had just one thread, and code didn't have to make any assumptions about synchronizations between objects within a process. To preserve this illusion and allow objects that were written assuming single-threaded COM to be used in a multithreaded environment, COM introduced the 'single' model, also known as 'legacy STA'. More details on this page, scroll down or search for "Legacy STA" for the details. COM basically puts all of these 'single' objects on the same [STA] thread - and uses whichever thread just happens to be the first to call CoInitialize. When you CoUninit and CoInit again on another thread, you're essentially restarting COM; so it's now the second thread that is the new "first thread to call CoInit", so that's why COM then ends up using that one...
(Legacy STA is such an old issue is was actually hard to track down any details; nearly all other articles mention apartment, free and both options; but there's rarely details about 'single'.)

QPointer in multi-threaded programs

According to http://doc.qt.io/qt-5/qpointer.html, QPointer is very useful. But I found it could be inefficient in the following context:
If I want to show label for three times or do something else, I have to use
if(label) label->show1();
if(label) label->show2();
if(label) label->show3();
instead of
if(label) { label->show1();label->show2();label->show3(); }
just because label might be destroyed in another thread after label->show1(); or label->show2();.
Is there a beautiful way other than three ifs to get the same functionality?
Another question is, when label is destroyed after if(label), is if(label) label->show1(); still wrong?
I don't have experience in multi-threaded programs. Any help is appreciated. ;)
I think the only safe way to do it is to make sure you only access your QWidgets from within the main/GUI thread (that is, the thread that is running Qt's event loop, inside QApplication::exec()).
If you have code that is running within a different thread, and that code wants the QLabels to be shown/hidden/whatever, then that code needs to create a QEvent object (or a subclass thereof) and call qApp->postEvent() to send that object to the main thread. Then when the Qt event loop picks up and handles that QEvent in the main thread, that is the point at which your code can safely do things to the QLabels.
Alternatively (and perhaps more simply), your thread's code could emit a cross-thread signal (as described here) and let Qt handle the event-posting internally. That might be better for your purpose.
Neither of your approaches is thread-safe. It's possible that your first thread will execute the if statement, then the other thread will delete your label, and then you will be inside of your if statement and crash.
Qt provides a number of thread synchronization constructs, you'll probably want to start with QMutex and learn more about thread-safety before you continue working on this program.
Using a mutex would make your function would look something like this:
mutex.lock();
label1->show();
label2->show();
label3->show();
mutex.unlock()
As long as your other thread is using locking that same mutex object then it will prevented from deleting your labels while you're showing them.

What is the difference between +[NSThread detachNewThreadSelector:toTarget:withObject:] and -[NSObject performSelectorInBackground:withObject:]?

They seem to perform a reasonably similar task: launching a new thread that performs that selector quickly and easily. But are there any differences? Maybe with regards to memory management?
Both are identical.
In iOS and Mac OS X v10.5 and later, all objects have the ability to spawn a new thread and use it to execute one of their methods. The performSelectorInBackground:withObject: method creates a new detached thread and uses the specified method as the entry point for the new thread. For example, if you have some object (represented by the variable myObj) and that object has a method called doSomething that you want to run in a background thread, you could could use the following code to do that:
[myObj performSelectorInBackground:#selector(doSomething) withObject:nil];
The effect of calling this method is the same as if you called the detachNewThreadSelector:toTarget:withObject: method of NSThread with the current object, selector, and parameter object as parameters. The new thread is spawned immediately using the default configuration and begins running. Inside the selector, you must configure the thread just as you would any thread. For example, you would need to set up an autorelease pool (if you were not using garbage collection) and configure the thread’s run loop if you planned to use it. For information on how to configure new threads
I presume they are the same, as - (void)performSelectorInBackground:(SEL)aSelector withObject:(id)arg; is defined in NSThread.h in the NSObject (NSThreadPerformAdditions) category. That is nothing conclusive, but that is evidence in that direction.

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