QT QThread::isrunning freeze program on Pi - c++

I'm testing a programm on my PI.When running it on the host pc no error is shown, instead , running it on pi (CM3) it freezes.
I'm trying to use multithreading.
From the main thread, in the constructor an QThread is started, then when I click on the button to open a new form the GUI freezes. In the button slot I need to check if the serial_works thread has been started in the constructor has finished before opening a new form, so I added a QThread::isRunning() check;
Main_Form::Main_Form(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::Main_Form)
{
ui->setupUi(this);
this->move(0,0);
this->setWindowFlags(Qt::Window | Qt::FramelessWindowHint);
connect(ui->btn,SIGNAL(clicked(bool)),this,SLOT(open_form()));
*serial_works = new SerialWorks();
serial_works->start();
}
void Main_form::open_form(){
std::cout<<"open form slot"<<std::endl;
int i = 0;
while(serial_works->isRunning()){
std::cout<<"WHILE"<<std::endl;
QThread::msleep(100);
i++;
if(i > 10){
serial_works->terminate();
}
Next_form *frm = new Next_form();
this.close();
frm->show();
}
the run method in the Serial_works class is
void Serial_works::run() {
my_function();
this->terminate();
this->wait();
}
void Serial_works::my_function(){
....stuff on serial
std::cout<<"serial works finished"<<std::endl;
}
on the output i get
//serial works finished
//open_slot_form
no WHILE is printed out on the console,thus the program get stuck on the while check
serial_works->isRunning()
Where is the problem? On the the host pc, the new form opens as expected.

You are trying to use QThread without understanding what is this object doing. What you want to do is asynchronous execution : Do some work and when you are done let me know.
Edit : What is Happening :
Client : main thread executes open_form before the worker executes run
Rasberry Pi : worker executes run before main thread executes open_form
On PI
serial_works->start() launch worker, which execute first, and complete my_function.
worker call this->terminate() and is now officially dead. terminate is a brutal way of stopping a QThread..I cannot even speculate whether wait() is called.
The main thread execute open_form, and the worker is already non-runnable. So the loop is not executed and Next_form is never going to be shown.
Error 1 :
Main_form::open_form()
is executing in the gui thread, and you are sleeping on a event. This is always incorrect. You GUI will freeze for the amout of time you are sleeping. Use signals and slots or events.
Error 2 :
Serial_works is likely a subclass of Qthread. You are confusing a thread of execution with the object managing that thread. You should not subclass QThread.
this->terminate();
this->wait();
The worker thread is executing that code. You are killing yourself then waiting on your death. So depending on the implementation you may wait forever , crash, etc....
What you need to do :
Use QFuture and QFutureWatcher.
//inside Main_Form
QFutureWatcher<ReturnValueType> watcher;
void Main_form::open_form(){
// Instantiate the objects and connect to the finished signal.
connect(&this->watcher, SIGNAL(finished()), &this, SLOT(SignalWorkFinished()));
// Start the computation.
QFuture<ReturnValueType> future = QtConcurrent::run(stuffOnSerialFunction);
this->watcher.setFuture(future);
}
// now handle work finish
void SignalWorkFinished()
{
QFuture<ReturnValueType> future = watcher.future();
//do whatever you like
}

Related

Cannot send events to objects owned by a different thread while runing a member method on another QThread

I need to run a method in my MainWindow class, in a different thread as it is a length and time consuming process.
This is what I tried:
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
initGui(ui);
// Create background worker thread
backgroundWorker = QThread::create([this] {
backgroundMethod();
});
// Define when finished with work
connect(backgroundWorker, &QThread::finished, [this] () {
qDebug() << "Background method has finished";
// Stop movie
ui->lblLoading->movie()->stop();
// go to next screen
ui->tabbarMainWidget->tabBar()->setCurrentIndex(1);
//show backup icon files
if(filesToBackup.size() > 0) {
qDebug() << "There are files to backup!";
ui->lblInfoImage->show();
}
});
// Start worker thread
backgroundWorker->start();
}
backgroundMethod
void MainWindow::backgroundMethod() {
for (int i = 0; i < 10; i++) {
qDebug() << "Hello World";
}
}
I am omitting alot of code as it is not necessary. The basic logic is as follows:
Start new thread using QThread::create()
Run the backgroundMethod() until completed while having the UI free for other work.
When the backgroundMethod() has finished, the QThread should emit the finished() signal.
I have a connection setup between the backgroundWorker thread's finished() and the lambda to run some more code.
The problem:
Background method has finished
QObject::killTimer: Timers cannot be stopped from another thread
ASSERT failure in QCoreApplication::sendEvent: "Cannot send events to objects owned by a different thread. Current thread 0x0x2801d950. Receiver 'lblInfoImage'
(of type 'QLabel') was created in thread 0x0x2688c4b0", file
kernel\qcoreapplication.cpp, line 578 04:11:28: The program has
unexpectedly finished.
In short, I am accessing the lblInfoImage on the backgroundWorker thread. I understood that using the signal/slot mechanism should cater for this issue, where my use of it is correct.
I am not sure why this is happening, I need some help in understanding what I did to cause the problem and how I can fix it
The problem is simple: you execute UI code on a non-UI thread which is strictly forbidden in Qt (and in many other UI frameworks across different languages). That happens because you do the connection wrong:
connect(backgroundWorker, &QThread::finished, [this] () {
...
});
That connection means: whenever QThread emits a finished signal run this function. The thing is, it will run the function in the context of the emitted signal which is another thread not the thread backgroundWorker lives in. So you have to provide the UI thread context for receiving this signal:
connect(backgroundWorker, &QThread::finished, this, [this] () {
...
});
Now the function provided will be executed in the context of the UI thread (this).

QT - Mainwindow doesn't update unless it's closed

I'm trying to update the main window by calling updateGUI function in a thread every 500 ms. The window is displayed but not updated with the new values unless I close the window. When I do so, a new window is opened with the new value. I found this question but it didn't answer my question. I knew that (as stated in qt documentation)
QApplication::exec enters the main event loop and waits until
exit() is called.
I tried to use processEvents() but the main window is opened and closed repeatedly and very fast that I can't even see it. Here is my code:
float distanceToObject;
bool objectDetected;
Modes currentMode;
void timerStart(std::function<void(void)> func, unsigned int interval)
{
std::thread([func, interval]()
{
while (true)
{
auto x = std::chrono::steady_clock::now() + std::chrono::milliseconds(interval);
func();
std::this_thread::sleep_until(x);
}
}).detach();
}
int updateGUI(void)
{
int argc = 0;
char **argv = NULL;
QApplication a(argc, argv);
MainWindow w;
// Set text of a label
w.setDistance(QString::number(distanceToObject));
// Also update objectDetected and currentMode values
w.show();
//a.processEvents();
return a.exec();
}
void sendMsg(void)
{
// Send heartbeat signal to another device
}
void receiveMsg(void)
{
// Read messages from the other device and update the variables
// These two values change continuously
objectDetected = true;
distanceToObject = 5.4;
}
void decide(void)
{
// The core function of the program. Takes relatively long time
// Run a decision-making algorithm which makes decisions based on the values received from the other device.
// Update some variables according to the made decisions
currentMode = Auto;
// Execute functions according to the made decisions.
setMode(currentMode);
}
int main(void)
{
timerStart(updateGUI, 500);
timerStart(sendMsg, 1000);
timerStart(receiveMsg, 10);
timerStart(decide, 500);
}
How can I update the main window with the variables' values correctly?
Your thread does not update the MainWindow, but it does create an entirely new QApplication and MainWindow on every iteration. Your thread should be stuck inside QApplication::exec until you quit the application (e.g. by closing the window). Only then should your thread's loop make further progress.
In general, you must be very careful when doing updates from outside the main thread, since typically GUI operations must be performed inside the main thread.
Think about using QThread, which already comes with its own event loop, which you can use to notify/update your window using a respective slot.
Without further details about what you are actually trying to achieve, it is not possible to give you further direction. I, at least, recommend that you create your QApplication and MainWindow inside the main thread (e.g. main). Then it depends what you are trying to 'update'. If you need to progress some data, then you can do that within your second thread and send the results to your MainWindow instance using signal-slot. If you need to draw onto the window, then this either has to be done in the main thread directly, or you might find a way to render into a separate buffer (i.e. QImage) from within your thread and then send this buffer to the main thread for drawing it into the window.
I try to sketch how something like this can be done. Notice, however, that this it neither complete nor compilable, but merely an outline.
First, you have your MainWindow and add to it a signal, that notifies all observers to start doing their work (will become clear in a moment). Furthermore, you add slots that will be invoked whenever one of your values changes. Those slots run in the main thread (and are members of the MainWindow) and thus can update the window however they need to:
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
// constructors and stuff
void startWorking()
{
emit startWorkers();
}
public slots:
void onModeChanged(Modes m)
{
// update your window with new mode
}
void onDistanceChanged(float distance)
{
// update your window with new distance
}
signals:
void startWorkers();
};
Next, you build a Worker class, that encapsulates all the 'background work' you like to do (basically what your thread did in your original code):
class Worker : public QObject
{
Q_OBJECT
public:
// constructors and stuff
public slots:
void doWork()
{
while(!done)
{
// do stuff ...
Modes m = // change mode
emit modeModified(m);
// do stuff ...
float distance = // compute distance
emit distanceModified(distance);
// do stuff ...
}
}
signals:
void modeModified(Modes m);
void distanceModified(float distance);
};
Note, that Worker must inherit QObject and that your doWork method must be a public slot. Furthermore, you add a signal for each of the values you like your MainWindow to be informed about. No implementation for them is needed, since it is generated by the Qt MOC (Meta Object Compiler). Whenever one of the respective values changes, simply emit the corresponding signal and pass the new value.
Lastly, you put everything together:
int main(int argc, char* argv[])
{
QApplication app(argc, argv);
MainWindow window;
// create a worker object
Worker* worker = new Worker;
// connect signals and slots between worker and main window
QObject::connect(worker, &Worker::modeModified,
&window, &MainWindow::onModeChanged);
QObject::connect(worker, &Worker::distanceModified,
&window, &MainWindow::onDistanceChanged);
QObject::connect(&window, &MainWindow::startWorkers,
worker, &Worker::doWork);
// create a new thread
QThread* thread = new QThread;
// send worker to work inside this new thread
worker->moveToThread(thread);
thread->start();
// show window and start doing work
window.show();
window.startWorking();
// start main loop
int result = app.exec();
// join worker thread and perform cleanup
return result;
}
Alright, let's go through it. First, you create your QApplication and MainWindow inside your main thread. Next, create an instance of your Worker object (could create multiple here). Then you connect the signals of the worker to the slots of the window and vice versa. Once these connections are established, whenever you emit a signal, the connected slot is invoked by Qt (and passed values are transmitted). Notice, that this connection works across thread boundaries. Whenever a signal is emitted from a thread different then the receiving object's thread, Qt will send a message, which is processed in the receiving object's thread.
Then you tell Qt that you want your worker to live inside another thread using QObject::moveToThread. See here for a very detailed explanation of how to correctly use QThread and objects inside it.
The rest is then simple. show your window and start processing. Here different ways are possible. I just call the startWorking method here, which then emits the startWorkers signal, which is connect to the worker's doWork method, such that doWork will start executing after this signal is received by the other thread.
You then call QApplication::exec which runs the main thread's event loop, where all these signals are processed by Qt. Once your application is closed (e.g. by calling quit or closing the main window) the exec method returns and you are back in main. Notice, that you need to correctly close the thread (e.g. by sending an addition signal that stops the while loop) and join it. You also should delete all the allocated objects (worker, thread). I omitted this here for simplicity of the code example.
Answering your Question
I have many functions, e.g., updateClips and mavReceive that should be called periodically and run independently from each other. I should create a different Worker class for each function, as each has different signals, and a QThread object for each of these functions, right? I don't need startTimer() anymore? If yes, how can I control the calling interval for each function (used to be done in startTimer()
from the comment:
The answer greatly depends on what exactly you mean by "should be called periodically". Who is supposed to call them? The user? Or should they just be executed periodically?
So in principle, you can have multiple workers in one thread. However, if they are supposed to do work all the time (spin in a while loop) it does not make sense, since one is running and all others are blocked. In that case you would have one thread for each worker.
If I understand you correctly, you are interested in updating something periodically (e.g. every 500ms). In that case I highly recommend using the QTimer. You can set an interval and then start it. The timer will then periodically emit the timeout signal, which you can connect to whatever function (more precisely slot) you want to have executed.
An updated version of the Worker could look like this:
class Worker : public QObject
{
Q_OBJECT
public:
Worker()
{
QObject::connect(&modeTimer_, &QTimer::timeout,
this, &Worker::onModeTimerTimeout);
QObject::connect(&distanceTimer_, &QTimer::timeout,
this, &Worker::onDistanceTimerTimeout);
modeTimer_.start(500); // emit timeout() every 500ms
distanceTimer_.start(100); // emit timeout() every 100ms
}
public slots:
void onModeTimerTimeout()
{
// recompute mode
Modes m = // ...
emit modeModified(m);
}
void onDistanceTimerTimeout()
{
// recompute distance
float distance = // ...
emit distanceModified(distance);
}
signals:
void modeModified(Modes m);
void distanceModified(float distance);
private:
QTimer modeTimer_;
QTimer distanceTimer_;
};
Notice, the connections established in the constructor. Whenever one of the timers times out, the connected slot is invoked. This slot then may compute whatever it needs to and afterwards send the result back to the MainWindow in the main thread using the same signal as before.
So, as you see, you can have multiple timers / re-computations / update signals within one Worker (and thus, one thread). However, the crucial point for an implementation is, how long the computations take. If they take very long (e.g. nearly as long as the intervals) then you should think about using multiple threads to speed up the computation (meaning: perform one computation in each thread). As I slowly seem to get a clearer picture of what you want to achieve, I am wondering whether it is only about these periodic updates that you 'misused' the thread for in your question. If this is indeed the case, then you do not need that thread and Worker at all. Then simply add the timers to your MainWindow and connect their timeout signal to the respective slot of the MainWindow directly.

Communicating with QProcess from a QThread

Structure Of Application:
MainWindow -> ProcessingThread(QThread) - > QProcess for Python Script
In the Run/Exec loop of Processing Thread I would like to interact with the process.
How do I go about it?
Current Problem:
I know both ProcessingThread(QThread) and its Run loop run inside different threads. Hence if I initialize the QProcess in QThread constructor I am unable to interact with the process because of following error:
QSocketNotifier: Socket Notifiers cannot be enabled or disabled from
another thread
and if I try to initialize the process in the Run Loop I get the following error:
QObject: Cannot create children for a parent that is in a different
thread
(Parent is ProcessingThread(0x984b2a0), parent's thread is QThread(0x940e180)),
current thread is ProcessingThread(0x984b2a0)
If I initialize the QProcess in ProcessingThread constructor, I am able to interact with the script perfectly.
Any suggestions?
Update: Also The reason for using QThread is because I am performing image processing, the Processing Threads keeps fetching images from camera. Some of these images need to be further processed by the Python script running in QProcess.
Update 2: CODE
void MainWindow::MainWindow(QWidget *parent)
{
...
debugProcessingThread = new DebugProcessingThread();
}
class DebugProcessingThread : public QThread
{
Q_OBJECT
...
private:
qProcess *myprocess;
}
DebugProcessingThread::DebugProcessingThread()
{
...
myProcess = new QProcess(this);
myProcess->start("python abc.py");
connect(myProcess, SIGNAL(started()), this, SLOT(processStarted()));
connect(myProcess, SIGNAL(error(QProcess::ProcessError)), this, SLOT(processError()));
connect(myProcess, SIGNAL(readyReadStandardOutput()), this, SLOT(readStandardOutput()));
myProcess->waitForStarted();
}
void DebugProcessingThread::processError()
{
qDebug("PROCESS ERROR");
qDebug() << myProcess->errorString();
}
void DebugProcessingThread::readStandardOutput()
{
qDebug("READ DATA");
qDebug(myProcess->readAll().toStdString().c_str());
myProcess->write("out.txt\n");
}
void DebugProcessingThread::processStarted()
{
qDebug("Process has started");
}
The above code works perfectly.
But I want to send and receive data from function:
void DebugProcessingThread::run()
{
myProcess->write("out.txt\n");
// This Throws socket Error
}
Keep long story short, you shouldn't instantiate anything you going to use in your new thread in the constructor, as every object instantiated there will get an affinity of the thread where your QThread object is created, common practice is either not to subclass QThread at all, just use QObject and moveToThread, and then connect some slot like init() to QThread started() signal, so you can do all initialisation inside the init() which will run inside a new thread, or if for whatever reasons you need QThread subclassing instantiate everything in run().
Also pay attention that QThread itself is nothing more nothing less then a wrapper of your real thread and stays as an object in a thread where you created it.

Launching a while-loop freezes program even if using another thread

In my (Qt-)program I need a continuous request of a value which I get from an external source. But I did not want that this request freezes the whole program, so I created a separate thread for this function. But even if it is running in a separate thread, the GUI freezes, too. Why?
Code for the request function:
void DPC::run()
{
int counts = 0, old_counts = 0;
while(1)
{
usleep(50000);
counts = Read_DPC();
if(counts != old_counts)
{
emit currentCount(counts);
old_counts = counts;
}
}
}
Read_DPC() returns an int value I want to sent to a lineEdit in my GUI.
The main class looks like
class DPC: public QThread
{
Q_OBJECT
public:
void run();
signals:
void currentCount(int);
};
This code is called in the main function as:
DPC *newDPC = new DPC;
connect(newDPC, SIGNAL(currentCount(int)), SLOT(oncurrentCount(int)));
connect(newDPC, SIGNAL(finished()), newDPC, SLOT(deleteLater()));
newDPC->run();
How can I prevent this code from freezing my GUI? What am I doing wrong?
Thanks!
It seems that you code run in GUI thread because you use run() method to start thread, so try to call start() as documentation and many examples said.
Try:
DPC *newDPC = new DPC;
connect(newDPC, SIGNAL(currentCount(int)), SLOT(oncurrentCount(int)));
connect(newDPC, SIGNAL(finished()), newDPC, SLOT(deleteLater()));
newDPC->start();//not run
Anyways you can call thread() method or currentThread() to see in which thread some objects live.

What happens to QThread when application is being closed without proper wait() call?

In the example below (inside Qt GUI application) a new thread is started (with an event loop in which I want some work to be done):
void doWork()
{
QThread* workerThread = new QThread();
Worker* worker = new Worker();
worker->moveToThread(workerThread);
connect(workerThread, SIGNAL(started()), worker, SLOT(startWork()));
connect(worker, SIGNAL(finished()), workerThread, SLOT(quit()));
connect(workerThread, SIGNAL(finished()), worker, SLOT(deleteLater()));
connect(workerThread, SIGNAL(finished()), workerThread, SLOT(deleteLater()));
workerThread->start();
}
startWork() can be a long running operation during which the application can be closed.
I expected that the application will not be closed as long as startWork() is being executed on the workerThread. It seems though, that when I close the last application window, the workerThread is gone instantaneously (during long running operation) and application closes without problems.
The questions arose:
Why was the workerThread wiped right away?
Is it some parent/child issue?
How Qt handles such situation?
Is it programmer mistake, not to call wait() on QThread (eventually)?
Even if so, I tried to wait() inside a slot for aboutToQuit() and application wasn't closed after long running operation was done (with setup as above). Only quit(); wait(); (inside the slot mentioned) allowed the application to close. Why?
QThread has, basically, a long-standing API bug: it isn't always in a destructible state. In C++, an object is considered to be in destructible state when it's safe to invoke its destructor. Destructing a running QThread is an error. A QThread is merely a thread controller, it's not the "thread" itself. Think of how QFile acts: you can destruct it at any time, whether it's open or not. It truly encapsulates the notion of a file as a resource. A QThread is too thin of a wrapper around the native (system) thread: when you destruct it, it does not terminate nor dispose of the native thread if there is one. This is a resource leak (threads are OS resources), and people trip over this issue over and over again.
When the application's main() function returns, your implementation of the C/C++ runtime library happens to terminate all of the application's threads, effectively terminating the entirety of the application. Whether this is the behavior you desire is up to you. You're supposed to quit() and wait() your event-loop-running thread. For threads without an event loop, quit() is a no-op and you must implement your own quit flag. You must wait() on the thread before you destruct it. This is to prevent race conditions.
Below is a safe wrapper for QThread. It is a final class, since you can't reimplement run. This is important, since a reimplementation of run could be done in such a way that makes quit a no-op, breaking the contract of the class.
#include <QThread>
#include <QPointer>
class Thread : public QThread {
using QThread::run; // final
public:
Thread(QObject * parent = 0) : QThread(parent) {}
~Thread() { quit(); wait(); }
};
class ThreadQuitter {
public:
typedef QList<QPointer<Thread>> List;
private:
List m_threads;
Q_DISABLE_COPY(ThreadQuitter)
public:
ThreadQuitter() {}
ThreadQuitter(const List & threads) : m_threads(threads) {}
ThreadQuitter(List && threads) : m_threads(std::move(threads)) {}
ThreadQuitter & operator<<(Thread* thread) {
m_threads << thread; return *this;
}
ThreadQuitter & operator<<(Thread& thread) {
m_threads << &thread; return *this;
}
~ThreadQuitter() {
foreach(Thread* thread, m_threads) thread->quit();
}
};
It could be used as follows:
#include <QCoreApplication>
int main(int argc, char ** argv) {
QCoreApplication app(argc, argv);
QObject worker1, worker2;
Thread thread1, thread2;
// Style 1
ThreadQuitter quitter;
quitter << thread1 << thread2;
// Style 2
ThreadQuitter quitterB(ThreadQuitter::List() << &thread1 << &thread2);
//
worker1.moveToThread(&thread1);
worker2.moveToThread(&thread2);
thread1.start();
thread2.start();
QMetaObject::invokeMethod(&app, "quit", Qt::QueuedConnection);
return app.exec();
}
Upon return from main, the thread quitter will quit() all worker threads. This allows the threads to wind down in parallel. Then, thread2.~Thread will wait for that thread to finish, then thread1.~Thread will do the same. The threads are now gone, the objects are threadless and can be safely destructed: worker2.~QObject is invoked first, followed by worker1.~QObject.
1) Is it parent / child issue?
Not in the case of your code - You're not parenting the QThread. Qt doesn't like you to just terminate the main thread if you've other threads running. You're likely to see it complain in the standard output that the other thread was still running when the application was terminated. However, Qt will kill the other thread, which is why there's a function to call and wait for the thread to terminate properly.
2) Is it programmer mistake not to call wait()?
Yes. If you're having issues with the Thread not quitting properly, it's because you're not handling it correctly, in which case you could open another question and show the code as to how you're handling the wait before quitting.
when I close the last application window, the workerThread is gone instantaneously
Note that there's a function in QApplication called setQuitOnLastWindowClosed, which you can set to false, to prevent the app automatically quitting on closing the last window.