Global variable declaration in Qt - multithreading

I have made a Gui thread and a QTcpSocket thread in Qt.I want to access data
from QTcpSocket thread to Gui thread.How to solve it?
Do i need to declare some global variable and how?

The easiest way is to communicate via signal-slot connections. There is one QObject in each thread. The sending object has a signal, which is connected to the slot of the receiving object in the other thread.
In this setup, you make sure that the objects on both ends of the connections are configured to live in the correct threads. You might need to call QObject::moveToThread(). QObject also has a property where you can get the current thread (for debugging purposes in this case).
Then just establish the signal-slot connection as usual. Since both objects are in different threads, when the signal is triggered, a slot invocation event will be placed in the event loop of the receiving flag. This is explained in the Qt documentation, look for Qt::QueuedConnection.

The QTcpSocket is created from the gui thread.
So at that point the gui thread has a pointer to the socket object.
It then creates a connection between a slot in the gui and a signal in the socket.
In the socket object whenever you get data you simply emit a signal containing the data, which will be picked up by the gui thread.
You can pass any Qt type eg QString, QByteArray (or a raw pointer), through a signal/slot very efficiently. The details if signals between threads are also handled automatically.

Related

How to create SignalHub in a QT application?

There is a multi-threaded application on QT5. Threads emits signals to each other. For example, the button click signal in the GUI comes in three separate threads, and each thread performs its own function. Is there an easy way to connect all signals to some object, let's call it SignalHub? And this SignalHub will receive all signals from all threads or objects, and any thread or object can be subscribed to the desired signal? Something similar to DBus, but only for several threads within a single QT application? Each thread or object should not receive its own signal. The purpose of this is to reduce the amount of code (there are several threads in the application, and each has multiple signals and slots). And it would be ideal to connect the necessary signals to (and from) the SignalHub only in new object's constructor or new thread's constructor.
Signals are thread-safe. So are connect() and disconnect(). Meaning: you can literally declare any object you want to be your "signal hub" and just connect the slots across threads as you desire. To what threads the objects involved belong doesn't matter. No problems.
To avoid receiving signals an object sent itself, you can simply do something along those lines:
void MyObject::someSlot() {
if(sender() == this) return;
}

Can Qt signals can be safely emitted from another QThread

I'm using some QThread in my application.
My objects "live" in different threads (their owner threads as Qt means it are different) and use signal/slots with queued connections to communicate.
Now, I have this problem :
Object "A" lives in QThread "A"
Object "B" lives in QThread "B"
Gui lives in the "main thread"
then :
Object "A" calls a method B::foo on "B" instance, from its own thread "A"
the ressources shared by this B::foo method are protected using a mutex, no problem here to execute B::foo from the thread "A"
inside the B::foo method, object "B" emit the signal barSignal
And I have some questions about his configuration :
Is it safe to emit a signal of object "B" from a thread which is not the "B" owner's QThread ?
Is it safe to use Qt::AutoConnection to receive this signal in a GUI object who lives in the "Qt main thread" ?
Is it safe to use a Qt::AutoConnection to receive this signal in a object "C" who lives in it's own QThread "C" ?
My test tends to say "yes" to everything.
By reading the Qt emit code, it seems to be ok.
But it didn't find anything in the Qt documentation about "emitting signal from a thread which is not the emitter's owner thread".
It's safe to emit signals from other threads, if you use auto or queued connections. Auto is deduced to be queued in situations where the signal is emitted in a thread in which the receiving QObject do not have affinity. Direct connections are not thread safe.
There is a "Signals and Slots Across Threads" section in the documentation that deals with emitting signals to objects in different threads.
Queued Connection - The slot is invoked when control returns to the event loop of the receiver's thread. The slot is executed in the receiver's thread.
also
The connection type can be specified by passing an additional argument to connect(). Be aware that using direct connections when the sender and receiver live in different threads is unsafe if an event loop is running in the receiver's thread, for the same reason that calling any function on an object living in another thread is unsafe.
QObject::connect() itself is thread-safe.

Qt slot simultaneous disconnect and call from different theads

I'm newbie to Qt. I haven't found an answer in a reasonable time and decided to ask here.
I have a thread, let's call it Thread1 with Qt object which have a connected slot. Signal is emitted from the same thread (Thread1).
And I'm disconnecting this slot from another Thread2.
Is this operation thread safe?
Are there any problems, if a signal is emitted and slot is disconnected exactly at the same time?
Just looking at the docs, it looks safe to me:
http://qt-project.org/doc/qt-4.8/qobject.html
Note: All functions in this class are reentrant, but connect(), connect(), disconnect(), and disconnect() are also thread-safe.
http://qt-project.org/doc/qt-4.8/qobject.html#disconnect
Note: This function is thread-safe.
Also make sure that you are using Queued Connections when you are connecting the signal of one thread to the slot of another. The Auto-connect may misbehave (and do direct connection) if both objects happen to be in the same thread during the time of the connection.
Hope that helps.
EDIT: More about Thread Safety:
http://qt-project.org/doc/qt-4.8/threads-reentrancy.html
http://qt-project.org/doc/qt-4.8/threads-qobject.html

Delphi7 How to make Com object wait until program initilisation is complete?

I have a Delphi7 program which implements a com server. Recently the time for program initialisation to complete has increased somewhat due to some new database queries. What I mean by program initlisation is the time it takes for the program to be able to process the incoming com calls in a meaningful way.
My question is how I can handle incoming com calls when the program is not properly initialised yet. Discarding the information contained in the call is not an option, the call needs to wait for the program to initialise.
Will a simple while loop using a boolean initialisation variable be sufficient?
I ask because I read that com calls are executed in the main VCL thread, which would suggest that a while loop would cause the program to hang (The initialisation takes place in the VCL thread as well).
Mutexes cannot be used to waitfor code executing within the same thread, right?
To put it another way, does a com call interupt execution of the (com server's) VCL thread until it is done or how does this concurrent execution of code within the same thread work?
Thanks for taking the time.
Move your database logic out of the main thread so it is not blocked anymore.
COM server (EXE) waits Applcation.Run before return the control flow to the COM client, so all forms and data modules should be initialized.
However, when a form creates another OLE object (i.e. open Word doc in FormCreate() event handler) this may interrupt waiting and return control to the COM client immediately.
Try to check all initialization code of the forms created before Applcation.Run to localize the problem.

Why are slots being called from the main thread?

I have a Qt application that has two threads: the main thread that handles the GUI and a second thread that manages network connections. Here is the thread code:
void thread::run()
{
QTcpServer server;
server.connect(&server,SIGNAL(newConnection()),this,SLOT(OnConnect()));
//...
}
When I put a breakpoint at the start of OnConnect() and debug the application, it announces that OnConnect() is being called from the main thread!
How can I have OnConnect() run in the same thread as the QTcpServer?
To give a more thorough answer, look a little deeper into how signal-slot connections and thread contexts interact. Basically, for more connections (auto-connect), the slot will be directly called if both the emitter and the receiver are in the same thread context, otherwise it will be a queued connection, and the slot will be run in the thread context of the object that contains the slot. In this case, it must be queued, which implies that your thread is part of the main application's thread context, not its own. This is reinforced by the documentation Qt provides for an overview of its threading, where it states that the QThread instance is "owned" by the thread context that created it, not the thread context that it represents. This means you have three main choices:
You can use moveToThread() to move the thread into its own context. Note that this may cause problems when deleting the thread unless you move it back to the context where it will be destroyed, and this can only be done in the source-thread context, so it would have to be done before the run function exited.
You can treat the QThread instance as a handle to the thread, not as being part of the thread itself. If you need things done in the context of the new thread, create a different object to handle those, and instantiate them in the context of the new thread (inside the run function). This is what I would recommend.
Force a direct connection. This means you would need to ensure the code running in the slot is thread-safe, ignoring Qt's built-in methods of making those functions thread-safe. This is what you have done.
It seems like the problem was that I wasn't passing Qt::DirectConnection as the last parameter of connect().
After adding that, it worked.

Resources