QThreads interruption with slots and signals - c++

I have a class which contains QThread. In the initialization function of this class the thread should be started. This works correct. in the thread there I have a while(bool certainCondition){} this certainCondition should be changed by a signal/slot connection.
The problem is that during the while is running the signal/slot is not opened.

You are not running an event loop in your thread, or you are blocking for a long time in your while-loop. Your slot cannot be called until you have returned control to the event loop, which will happen after you have finished the while-loop.
As a workaround, you can try calling QCoreApplication::processEvents() inside your while-loop.

In order for signals/slots to work across threads, the event loop must run.
If you use a while loop, the event loop is never run, and hence signals are not received.
This is how you normally run the event loop:
void Thread::run()
{
...do something
exec(); //<<this runs the event loop
}
Now, your problem is that you want continuously run some code until some condition is met. In the above code, this won't work, because of the exec() call.
There are 2 possibilities to solve that (depending on what you want to achieve in your loop):
Use a QTimer, that fires let's say every 5 seconds, and calls a slot which executes your repeating code.
Use a QWaitCondition to check for a certain condition to be fulfilled; but then you cannot use signals and slots; instead you have to trigger the QWaitCondition.

Related

How to know in which thread Qt executes slots?

I use Qt and I need to execute some code in the main thread. I realized that successfully using signals & slots.
My question is, even tho it's working atm: what defines in which thread a slot is executed as the direct result of signal emitting?
Is it inside the thread that executes the connect() function or what?
It depends how you set up your connection.
If you use Qt::DirectConnection, the slot will be executed immediately in the signaling thread, bypassing any event loop.
If you use a Qt::QueuedConnection, it will be executed in the receiving objects event loop, in the receiving objects thread.
If you don't specify the connection type, it defaults to Qt::AutoConnection, which defaults to Qt::QueuedConnection if the two QObjects have different thread affinities.
A directly connected slot always executes immediately, before the signal returns.
A slot connected via a queued connection will execute in the event loop running in its object's thread(). The slot is called from within the exec().
The default automatic connection determines which method to use every time the signal is emitted. If the target object is in the same thread, the slot will be called immediately from the signal, otherwise an event will be posted to the target object, picked up by the target thread's event loop, and executed there.
The logic is, effectively:
void mySignal(params) {
// moc-generated code below
for (all directly connected slots, all automatically connected slots in this thread):
slot(params);
for (all queued-connected slots):
QCoreApplication::postEvent(slot's object, new QMetaCallEvent(slot, params));
}
The direct connection doesn't require an event loop to work, and is like any indirect function call through a function pointer.

QT : How to determine if the event processor is busy

In my current Qt application I am attempting to shut it down using
QCoreApplication::quit();
Now it takes more than a minute for the application to shutdown. I believe this is because the event processor of the main form is busy. My question is : Is there a way for me to determine what the cause of this might be. Here are somethings that I suspect
1-Queued Connections.
I have a lot of queued connections. Maybe some of those connections dont get processed
2-Event Loop.
May be the event loop is busy doing something that I dont know (expect)
Any suggestions on what I could do to check why the app takes so long to close ?
Update:
I tried QCoreApplication::hasPendingEvents() and that returns true
There's no such thing as queued connections that are "not" processed, or event loop being "busy". An event loop is, essentially, this (in C++ pseudocode):
forever {
while (! nativeEventQueue.isEmpty()) {
QueueEntry entry = nativeEventQueue.take_first().convert();
QCoreApplication::sendEvent(entry.object, entry.event);
delete entry.event;
}
while (! eventQueue.isEmpty()) {
QueueEntry entry(eventQueue.take_first());
QCoreApplication::sendEvent(entry.object, entry.event);
delete entry.event;
}
waitFor(eventQueue, nativeEvents);
}
All of the event processing is done by sending some QEvent to a QObject. That's all that the event loop does. Some events result in the signals being emitted. It's not the event loop that is busy, it's the code that runs in the QObject::event and overridden implementations! This code blocks the event loop, since when it runs, the event loop's code is in the same thread and is on the call stack - it can't run.
Your code in slots connected to signals in Qt widgets and other objects is really executed while QCoreApplication::sendEvent and QCoreApplication::notify is on the call stack, with the event loop (a QAbstractEventDispatcher) somewhere deeper in the call stack, and finally a QEventLoop under it.
If your code executes at a pace that is slower than the events are added to the queue, you will have problems.
This trivial example demonstrates such code. In real programs it'll be of course "obfuscated", but the problem often reduces to:
void Class::customEvent(QEvent * ev) {
...
QCoreApplication::postEvent(this, new EventFoo(...));
...
QCoreApplication::postEvent(this, new EventFoo(...));
...
}
The explicit event posting can be expressed very differently. For example, it could be you sending a signal to yourself:
void Class::mySlot() {
...
emit signal1();
...
emit signal2();
}
If both signal1 and signal2 are connected to mySlot through a queued connection, your application will run out of memory, as the event queue will only grow, never shrink. It may still appear responsive.

How do I stop and start a loop in QT?

I've been trying to figure out how to make the program stop in a for-loop and wait for a button to be clicked and the for-loop continues.
Isn't there any easy way to stop the loop like QSystem.stop() and in the button clicked function QSystem.star() and the loop continues.
In C++ you could use system("pause") or the program stopped when you used a cin<<. But how do i do this in QT?
Since the userinterface needs its code to run, if you halt event loop (which also means that any function that gets called from within the event loop is blocking, waiting for some event), you also halt the user interface, which means clicks into the window won't be processed. That's why in event based programming, which is what all UI kits do, it is essential to return to the main event handler loop as quickly as possible.
What you can do is create a second thread and wait on a condition variable. The GUI thread can signal that condition variable in the button click event slot.
In C++ you could use system("pause") or the program stopped
Exactly: The program is stopped. Which means it won't fetch events from the operating system. However receiving data from stdin is not an event. It's blocking on streamed I/O. Graphical user interfaces are event based though.
Note that conceptually it's not really impossible to think of a user interface to provide streaming I/O channels. However that doesn't work in single threaded programs. You need parallel execution (coroutines, threads, or such) for a concept like this to work.
You don't need threads, nested event loop will do the job.
int waitUntilSignalIsEmitted(QObject *sender, const char *signal) {
QEventLoop loop;
connect(sender, signal,
&loop, SLOT(quit()));
return loop.exec();
}
// usage:
while(yourLoopCondition) {
// some stuff
...
// pause here
waitUntilSignalIsEmitted(yourContinuationButton, SIGNAL(clicked()));
// loop continuation
...
}

Qt Thread object only sending signal as Qt:DirectConnection - why?

I have a class derived from QThread: class MyClass : public QThread
This class is connected with a slot of another object. Originally this was connected as Qt::AutoConnection. But then - as soon as the thread is started (MyClass::run()) - the signal is no longer "reaching the slot" (why?).
// connected before myObject->run()
s = QObject::connect(
_myObject, SIGNAL(signalLogMessage(const QString&, QtMsgType)),
this, SLOT(slotLogMessage(const QString&, QtMsgType)), Qt::DirectConnection);
My first idea was that I need to force Qt::QueuedConnection (this / _myObject will be cross threaded). In this case it does not work at all. Only Qt::DirectConnection works. After the thread is started, IMHO Qt::QueuedConnection is the correct choice (cross thread).
Any idea what is going wrong? The connection itself seems to be correct, otherwise it was not working at (mean even not with Qt::DirectConnection).
Edit 1: -- As of hyde's answer / Nikos' comment
As of right now I think hyde's answer / Nikos' comment are pointing out the root cause. My QThread is running it's own message loop for another application. This is the reason why it is running in its own thread and is basically an infinite loop
run() {
// exec(); // while not reached
while (_runMessageLoop && ...) {
hr = CallDispatch(.....);
if (hr== 0) QThread::msleep(100);
// QCoreApplication::processEvents();
}
}
Guess due to this infinite loop the Qt message loop is not running and no signal / slots are processed (is this correct?) When forcing Qt::DirectConnection the methods are called directly with no Qt message loop required, this might be the reason why this is the only connection type working.
The question is now, how can I combine the Qt and my own message loop (if this is feasible)? Cannot call exec() before the loop (because then it is in the Qt loop), and just the QCoreApplication::processEvents(); in "my loop" is still not working.
=> see new Question here: How to combine own message loop and Qt event loop?
Hard to say without seeing all the code, but it may be because of this:
QThread object itself is not the thread, it's the thread controller. Most importantly, QThread object's thread affinity should not be the thread it controls. If your thread runs Qt event loop, then it's best to avoid subclassing QThread. Instead, have your logic (inter-thread slots etc) in another QObject, which you move to the thread you created with moveToThread after creating it. Only real reason to subclass QThread is to override run() method with one which does not call exec().
Related reading:
https://www.qt.io/blog/2010/06/17/youre-doing-it-wrong
Addition:
If you override QThread::run(), you have to call QThread::exec() there or event loop won't be running and no non-direct signal gets delivered to any QObject with that thread affinity. If you want to have your own event loop, that is possible, you just have to call QCoreApplication::processEvents() to process Qt events.

QThread passing data to and from

I will try to explain what my program used to do and what I am tring to change:
I had this function that ran on a button click from the the main thread in class MainWindow : public QMainWindow :
The function looks like this and is specified inside another file:
void MakeMeshStructure(MeshStructureLayers layers,
Handle_AIS_InteractiveContext theContext,
Handle_TDocStd_Document aDoc,
MyMesh &mesh,
int detail_vertex,
double insulation_thickness,
OpenMesh::VPropHandleT<MyMesh::Scalar> _max_beam_offset);
}
What it does is: it works on mesh and creates geometry for every vertex, face and edge of the mesh. This geometry gets displayed with theContext. This process takes very long (30 min) and blocks the gui.
What I would like to do is to have as many threads as QThread::idealThreadCount() and to free the gui when it computes and make it faster. (Is this the right thinking?)
I would like to divide my mesh into equal parts and pass this range of vertices to my function (above) to only work with one vertex range for a seperate tread.
I have a problem to figure out how to pass this data around and to make it thread safe.
I know its alot of code but here is my attempt at solving it:
http://pastebin.com/u/mzagar
The problem is getting all the data around in the right way and getting the threads to work. Where do I have to use mutexes. On every data that can get writen at the time of the thread work by the mainthread? Very confused. ty
edit:
I edited my code: http://pastebin.com/u/mzagar
I made a struct cadData to pass the data around. This is how I start threads:
connect(this, SIGNAL(startMake1(cadData)), cThreads.at(0), SLOT(MakeMesh(cadData)));
//...
cThreads.at(0)->moveToThread(threads.at(0));
//...
threads.at(0)->start();
//...
emit startMake1(aCadDatas.at(0));
//...
The problem is threads dont seem to work at the same time and also the gui freezes. Process goes in like this:
GUI freezes
things in thread 1 get done
things in thread 1 get done again
things in thread 2 get done
things in thread 2 get done again
...
GUI unfreezes
Any ideas why?
edit2:
I removed the multiple runs of the same thread by moving this to the class constructor:
connect(this, SIGNAL(startMake1(cadData)), cThreads.at(0), SLOT(MakeMesh(cadData)));
//...
cThreads.at(0)->moveToThread(threads.at(0));
//...
threads.at(0)->start();
Since you're using QThread, you can probably avoid explicit use of mutexes and such by using Qt's thread-safe slots-and-signals mechanism to do the work for you. You would basically package the data you need to send to the thread into an object, then emit a signal that has that object as an argument. The thread would receive a copy of that object in a slot (that you had previously connected to your signal) and start using the data then. To get data back from the worker thread to the main thread, you'd do the same thing again in reverse. Here's an article with some example code.
To add to Jeremy's answer: You can do the same by sending events between QObjects instead of using the signal-slot mechanism. Use whichever is most convenient for you.
The key is to leverage Qt's built-in event loop mutex. When you're sending signals to objects living in a thread different from the sender, the signal gets converted into a QMetaCallEvent and is posted to the event queue of the receiving QObject. This is done in a thread safe manner of course, and all one has to do is to leverage it. Sending explicit events works the same way. The event loop spinning in the thread where the receiver lives simply picks up QMetaCallEvents and executes slot calls accordingly, or dispatches your events to your implementation of customEvent() method.
When you start a raw QThread, the default implementation of the run() method spins up an event loop. You'll notice that such a thread is effectively idle and does not consume any CPU resources: the event queue is empty, and the event loop is blocked, waiting for someone to post an event to its queue. Once you move some QObjects to such a thread, the queued signal-slot deliveries will be done via the event loop of that thread. It works the same whether it's the GUI thread, or any other thread. The GUI thread is not special in any way when it comes to receiving events or queued signals.