I have some rough code that I've been experimenting with:
someserver.cpp (a GUI)
#include "server.h"
#include "ui_server.h"
Server::Server(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::Server)
{
ui->setupUi(this);
}
Server::~Server()
{
delete ui;
}
void Server::onBtnStartClicked()
{
QThread worker;
worker.start(); // Start worker thread that goes into an infinite loop with a blocking call
}
void Server::onBtnExitClicked()
{
// How do I cleanly stop worker from running?
QApplication::quit();
}
worker.cpp
#include "worker.h"
Worker::Worker(QObject *parent) :
QThread(parent)
{
}
void Worker::run()
{
for (;;)
{
// a blocking IO call here like pipe, or msgrcv
// process data received
}
}
Since the worker thread runs in a forever loop with a blocking IO call, how will I be able to structure this so that when the Stop button is pressed in the GUI thread, the worker thread is stopped cleanly?
Quit is suited for a QThread starting it's event loop. The poll call will at a point in time return something, then the loop with run again, that's why the exit variable is used, once it's set to 0, next time poll returns, it will get out of the loop and end things gracefully. I dont inherit Qthread for my object.
A QThread object manages one thread of control within the program. QThreads begin executing in run (). By default, run () starts the event loop by calling exec () and runs a Qt event loop inside the thread. You can use worker objects by moving them to the thread using QObject::moveToThread ().
For example, a thread blocked indefinitely on an I/O operation may never return to check if it’s been killed. To correctly deal with this case, thread needs to be carefully programmed to utilize timeout loops as shown in the code given below. ...
It is important to remember that a QThread instance lives in the old thread that instantiated it, not in the new thread that calls run (). This means that all of QThread's queued slots and invoked methods will execute in the old thread.
You could of course put a boolean value within the for loop in Worker::run()
checked every iteration, which breaks on ==true and is set by the gui Stop button. Of course, this won't quit the thread while execution is blocked.
Probably better is to get rid of the for
loop and use Qt's signals and slots to setup a callback function, connected to a signal like QIODevice::readyRead()
. These will be called only when there is information available in the socket/pipe whatever. Any other time you'll be able to quit the thread with QThread::exit()
. You'll need to call QThread::exec()
at some point as well to get the event loop going.
in infinity loop paste this code and enjoy...
QTime dieTime = QTime::currentTime().addMSecs(1);
while( QTime::currentTime() < dieTime ) {
QCoreApplication::processEvents( QEventLoop::AllEvents, 1);
}
don't forget
#include <QCoreApplication>
#include <QTime>
see you
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With