Using Qt signals/slots instead of a worker thread - c++

I am using Qt and wish to write a class that will perform some network-type operations, similar to FTP/HTTP. The class needs to connect to lots of machines, one after the other but I need the applications UI to stay (relatively) responsive during this process, so the user can cancel the operation, exit the application, etc. My first thought was to use a separate thread for network stuff but the built-in Qt FTP/HTTP (and other) classes apparently avoid using threads and instead rely on signals and slots. So, I'd like to do something similar and was hoping I could do something like this:
class Foo : public QObject
{
Q_OBJECT
public:
void start();
signals:
void next();
private slots:
void nextJob();
};
void Foo::start()
{
...
connect(this, SIGNAL(next()), this, SLOT(nextJob()));
emit next();
}
void Foo::nextJob()
{
// Process next 'chunk'
if (workLeftToDo)
{
emit next();
}
}
void Bar::StartOperation()
{
Foo* foo = new Foo;
foo->start();
}
However, this doesn't work and UI freezes until all operations have completed. I was hoping that emitting signals wouldn't actually call the slots immediately but would somehow be queued up by Qt, allowing the main UI to still operate.
So what do I need to do in order to make this work? How does Qt achieve this with the multitude of built-in classes that appear to perform lengthy tasks on a single thread?

If you're doing a length job in the UI thread the UI is going to freeze. One way to avoid this is to call once in a while QCoreApplication::processEvents().
You should be VERY careful however to understand what this does before you decide to do it. Calling this function means that a GUI event can fire in the middle of your operation. If this event can in turn create some more jobs you can end up starting a new job while in the middle of the old job.
I wouldn't be so quick dismissing the worker thread approach. It has the advantage of completely separating the work from the GUI so you are certain that something that began is going to finish.
You should also consider that Windows especially sometimes introduces non trivial delays to GUI loops. If the host is somewhat busy or in a memory thrashing state you'll find that GUI events may take up to several long seconds to finish and return control to your processing.

Use QThread with a run method like this:
void run(){ exec(); }
this will provide another execution loop, where you can do your "hard work" without acutally freezing the UI.
Note: Make sure to actually use the thread's execution loop by adding
moveToThread(this);
at the end of the Constructor of your QThread derived Thread class (the doc doesn't say much about it)

Related

Multi-threading design along with an undo/redo stack

I have this call stack to perform a heavy computation:
// QML
StyledButton {
onButtonClicked: {
registeredCppClass.undoHandler.createCommand()
}
}
void UndoHandler::createCommand()
{
m_undoStack->push(new Command());
}
class Command : public QUndoCommand
{
public:
Command();
virtual ~Command();
virtual void undo();
virtual void redo();
// ...
private:
// Handler does the logic
LogicHandler *m_logicHandler;
// Output by logic handler
QString m_outputName;
};
void Command::redo()
{
if (/* */) {
} else {
// Run heavy computation
m_outputName = m_logicHandler->run();
}
}
QString LogicHandler::run()
{
// Heavy computation starts
}
Intention
I intend to implement QThread by this approach to prevent GUI from getting non-responsive while heavy computation is being done. But I don't know where QThread and Worker class need to be implemented. Should they be within:
UndoHandler::createCommand
Command::redo
LogicHandler::run
... ?
What is the best location for QThread and Worker considering their signal-slot connections?
The general advice is to never read QThread documentation. Follow that up with never read Linux thread documentation. I say this as someone who has written quite a few books on software development.
The long answer is threading wasn't well thought out early on and there is a lot of, now bad, information out there. During Qt 3.x and I believe early Qt 4.x one was supposed to derive a class from QThread and override the run(). You can imagine just how well that worked for newbie developers unfamiliar with threads in general and unable to design in mutex or other access protection when manipulating things in multiple threads.
Your design makes it appear you have read some of this documentation. It's still floating around out there.
At some point during Qt 4.x we were no longer supposed to derive from QThread. Instead we were supposed to just create a QThread and moveToThread(). Kinda sorta worked but you could still end up with "dangling threads" if your program didn't follow the happy path through the code.
Around the same time, at least as far as my exposure, we also got a global thread pool.
Your design is really flawed because you looked at old doc. Not your fault. The old doc tends to turn up first in searches.
Visit this GitHub repo and pull down the project. The only dev_doc setup documentation I have completed is for Fedora. I will be working on Ubuntu this morning if I don't get interrupted. Be sure to check out the diamond-themes branch.
Yes, this is using CopperSpice, but CopperSpice is a fork of Qt 4.8 and this is the only concrete code example I could think of off the top of my head. You can build and run the editor or you can poke-and-hope by reading advfind_busy.cpp. What you are looking for is how QFuture is used. That source file is only about 200 lines long and it has a short header file.
Throw out your current design. You need QFuture and QtConcurrent::run().
Note: The header files for these things are different in name and location when compared to current Qt 5.x. That much you will need to look up if you choose to stay with Qt. How you use this stuff is not.
Note 2: If you don't have some kind of throttle control to limit each of these tasks to a single thread instance you will need to dynamically create and destroy QFuture objects. This means you have to have some kind of list or vector keeping track of them and your object destructor needs to walk that list killing off the threads and deleting the objects.
If you want to go on a journey setting up CopperSpice on Ubuntu it is spread across a multi-part blog post starting here.
IMHO, your intentions are correct, and you are headed in the right direction (leaving aside the argument for using QtConcurrency -- thread pools and futures -- since that's not pertinent to the immediate question). Let's address the first part: the objects and execution flow.
As the classes have been outlined in the code snippets, you will need to take extra care to correctly push them across thread boundaries. If you think for a moment, the worker object is created in the calling thread, therefore some of the object's members will also be created in the calling thread. For members which are pointers, this does not pose much of a problem, because you may elect to delay the creation of those objects until after the enclosing object instance has been created and moved to the worker thread. But, embedded objects are created when the object is constructed. If the embedded object derives from QObject, it will have its thread affinity set to the caller thread. In such a case, signals won't work properly. To alleviate this problem, it is often easiest to pass the work thread to the worker object's constructor, so the worker object is able to move all of its embedded objects to the worker thread.
Second, assuming the following:
Command holds a unique instance of LogicHandler, and
LogicHandler does not have state, and
LogicHandler is a subclass of QObject, and
LogicHandler is the worker class
My advice would be to place the spinning up of the thread in Command::redo, then connect the signals similar to advice given at the bottom of this article. Also, you would not set Command.m_outputName to the return value of LogicHandler::run. LogicHandler::run should return void. Instead, you should add a signal to LogicHandler that emits the string value when it has finished processing; then, add a slot in Command to handle that. A QString can easily be marshaled across thread boundaries (make sure you make the connections of the proper type, see here).
The connecting of the worker startup method, to the threads started signal gets the execution started. There is no need to inherit from QThread and override run. The worker should also emit a finished signal, that should be connected to the thread's quit slot. The worker's finished signal should also be connected to both the thread's and worker's deleteLater slot. When these are setup, just call the thread's start method.
From there, the execution will return from redo, and you will be notified that the worker is finished when it emits a signal (the one I mentioned that you will need to add) and passes the output string. If the lifetime of the worker is different (I'm guessing longer, since you need to spin up a thread to do long operation) from the instance of Command, then you will need to connected the return value signal from the worker object to a different object.

Using Qt signals and slots vs calling a method directly

Lets say I have a main window with a slider and a widget inside that window with a method called setValue(int). I'd like to call this method every time the value of the slider has changed.
Is there any practical difference between the two following ways of achieving it:
1
void MainWindow::on_slider_valueChanged(int value)
{
ui->widget->setValue(value);
}
2
// somewhere in constructor
connect(ui->slider, SIGNAL(valueChanged(int)), ui->widget, SLOT(setValue(int)));
For me the first approach looks better, because it possibly avoids some overhead related to signals and slots mechanism and also, allows me to process the value before sending it to widget, if there's a need for it.
Are there any scenarios where the second solution is better?
Both approaches use signal-slot connections. In the first case, the connect call is made by QMetaObject::connectSlotsByName() called from setupUi. In the second case, you explicitly call connect yourself.
Also, the first approach is unnecessary in Qt5 when using C++11. You can modify the value in a lambda:
QObject::connect(ui->slider, &QAbstractSlider::valueChanged,
[this](int val){ ui->widget->setValue(val*2); });
To protect from deletion of ui->widget, you should use a QPointer:
class MyWindow : public QMainWindow {
QPointer<QAbstractSlider> m_widget;
...
public:
MyWindow(QWidget * parent = 0) : QMainWindow(parent) {
...
setupUi(this);
m_widget = ui->widget;
QObject::connect(ui->slider, &QAbstractSlider::valueChanged,
[this](int val)
{
if (!m_widget.isNull()) m_widget->setValue(val*2);
});
The overhead of signal-slot connections is quantified in this answer.
Signal/slot advantages:
multiple slots can be connected to single signal, and you don't bother with allocating and freeing memory for this
you can handle multithreading with this
Signal/slot drawbacks:
a little slower than direct call
significantly slower if the slot is virtual
QObject is rather heavy thing, so you usually try to avoid constructing billions of them
More details are available here
The main difference, in your example, of using a signal instead of a direct call, is to allow more than one listener.
If you directly call your widget setValue(), then only that one widget will receive the C++ signal.
If you use a Qt signal, now any other object can connect to receive the event whenever it occurs.
If you do not foresee any other object to ever want to receive the value by signal, I would not bother with such. A direct call is definitively a lot faster (between 3 and 6 CPU instructions instead of dealing with strings to find receivers!), but as Paranaix mentioned, in a GUI it may not be much of an issue (although in this case it could become a problem on older computers if you send all those signals while moving the sliderbar.)
I prefer the second method, since it happened that I forgot to delete the "auto-connect-slots" when the UI-element was removed, causing dead code. AFAIK it is the same "behind the scene" (look at the auto-generated qt-files).
When you would like to modify the value I would prefer following method:
connect(ui->slider, SIGNAL(valueChanged(int)), this, SLOT(myOwnSlot(int)));
void MainWindow::myOwnSlot(int value) {
/** do stuff */
ui->widget->setValue(value);
}
Greetz
Signals & Slots is a different coding style. You can do things with signals that can be useful and neat work arounds to traditional c++. For example you can emit const signals from const functions and have them connect to non const slots (where as in c++ you cannot make non const calls from a const function). I've never liked using mutable objects, so signals provide a clean work around for me.

How do some Qt functions not block?

When I call QNetworkAccessManager::get() or QNetworkAccessManager::post() or many other methods the program flow continues on after the call and if I want further interaction, like getting what was received from the server, I need to use signals/slots. Do these functions run in their own thread? But the times I have used threads I have had to call something like MyClass::start() which doesn't happen when I call get() or post().
The times I have built a threaded class, the only way to start a function in the class is through MyClass:start() and MyClass::run(). But right now I have a class that has all sorts of functions in it that get called, and these functions should run in the background so that the main application can later receive a signal from those functions.
Hypothetically I'd have something like this
class MyClass
{
public:
void func1();
void func2();
};
MyClass::func1()
{
// move off into other thread
// do stuff
emit signal1(data1)
}
MyClass::func2()
{
// move off into other thread
// do stuff
emit signal2(data2)
}
I should be able to access MyClass::func1 or func2 directly which would be cumbersome if the only was to access them were through MyClass::start().
I hope this makes sense, I'm more a php person, these things are a bit foreign to me.
In sum, I'm looking to have a class, with multiple public functions all of which can be called on their own thread. I think. Maybe I'm on the wrong track.

Threads inside a qt class

I have this class inside a qt application that has some data defined:
class TableView:public QWidget
{
Q_OBJECT
public:TableView (QWidget * parent = 0);
std::vector < float > arr;
and some class functions and so on..
Now I want to add a socket server in another thread (posibly from inside this class) that is able to access data from this class when it recives something from the socket, calculate
new data and return.
For the test I used:
//defines
DWORD WINAPI SocketHandler(void* lp);
DWORD WINAPI starttremeshserver(void* lp);
CreateThread(0,0,&starttremeshserver, (void*)csock , 0,0);
This works. Now I need something easy and platform independent. Maybe something with qthread since I am working in qt.
So the question is, can I make a new thread function inside a class that can access class data. ty
Qt provides everything you need. Your needs are as follows:
Thread-safe (serialized) access to the data members of the TableView class.
Networking primitives.
Flexibility to move network access to a separate thread.
You are probably receiving data from the network, and want to update the arr member. You'd do it like so:
Create a QObject-derived class, say Processor, that has a slot that sets up the network connection (probably a QTcpServer). Upon a connection, use QTcpSocket to exchange data. Make sure all your data handling is done in slots in the class. When you have new values to update in the vector, simply emit some signal, like hasFloat(int,float).
Add a setFloat(int,float) slot in the TableView.
Connect the setFloat signal from the instance of Processor to your TableView.
At this point, everything runs in the GUI thread, but the code is non-blocking since you never wait for network data; you respond to the signals emitted by QTcpServer and QTcpSocket. You can leave it like that if you wish.
Having the Processor class run in a separate thread, if your benchmarking shows that your main thread is CPU bound, is then trivial:
int main(int argc, char** argv) {
bool separateThread = true;
QApplication app(argc, argv);
TableView view;
Processor proc;
connect(&proc, SIGNAL(hasFloat(int,float)), &view, SLOT(setFloat(int,float)));
QThread thread;
if (separateThread) {
thread.start();
proc.moveToThread(&thread);
}
view.show();
const bool rc = app.exec();
if (thread.isRunning()) {
thread.exit(); // tells the event loop in the thread to bail out
thread.wait(); // waits for the above to finish
}
return rc;
}
There's this misconception that spreading things across threads somehow magically makes them better. Threads are a solution to a particular problem: CPU-boundedness of the computations being done, and blocking APIs. If your processing is trivial, you are not likely to be CPU bound. Qt provides nonblocking, asynchronous networking. Thus, usually, spinning a second thread is entirely unnecessary.
You must show real numbers first to show you otherwise. Else you're buying into the cargo cult of threading: oh, it's networking, it must go into a separate thread. Nope, not necessarily. Measure first. Understand what you're doing.
The reason for thread safety in the above code is as follows: when you move the Processor instance to a different thread, Qt will reconnect all signal-slot connections using Qt::QueuedConnection type. Thus, when Processor emits hasFloat, it will internally cause an event to be queued in the event queue of the thread where TableView lives -- the GUI thread, in this case. When the event loop spins (here it'd be the application's event loop) -- it'll pick up the event and execute a call to TableView::setFloat. This ensures that the access to the arr data member is serialized and there are is no possibility of concurrent access from multiple threads.
I'd personally look for more high level socket support, something based on boost perhaps, anyway for threads you can use <thread> in C++11.
To answer your specific question:
class Foo
{
private:
void spinthread()
{
thread t([this] {
this->bar = 12;
});
}
private:
int bar;
}
If you're using Win32 threads API, the thread proc has a parameter which you can use to pass your instance to during the CreateThread call.
Qt has threading support as can be found here.
In addition to threads and accessing the data, you'll need synchronization for thread-safe code. This is called pthread mutex in linux, and in Qt its called QMutex as mentioned here.
You can find the Qt networking primitives here.
Using the Qt implementation of these threading and networking primitives will be portable, so should work for you on windows.
Regarding your question about creating a thread function from a class that accesses data on that class, the answer is yes. Instead of creating a thread function, it would be better to create a thread object, namely a QThread. When you create the thread object, you'll need to pass a reference to the instance of said class, which will allow the thread to access the class instance.

QtScript and threads

I want to run several concurrent jobs from QtScript script:
function job1() { ... }
function job2() { ... }
runConcurrentJobs(job1, job2)
The jobs a essentially sequences of remote procedure calls (ZeroC Ice), which need to synchronize at several points.
The Qt 4.8.0 documentation says nothing about QScriptEngine thread-safety. My questions:
Is it safe to use single QScriptEngine to exectute QtScript functions from multiple thread concurrently?
What approach would you recommend to accomplish the task?
Notes:
Scripts are edited not by programmers but also by electric engineers and I want to keep the script as simple and clean as possible.
QScriptEngine is documented as "reentrant", meaning, essentially, you can use it multi-threaded, but only one QScriptEngine per thread.
Now, if functions job1() and job2() can be run concurrently at all, in principle, it should be possible to separate them into two distinct QScriptEngines (easy, if neither the functions use local variables, only, more difficult, if globals are involved).
Implement runConcurrentJobs() as a Q_INVOKABLE function (or slot) in C++.
In there, do something like
void runConcurrently (const QString &functionname1, QString &functionname2) {
MyScriptThread thread1 (functionname1);
MyScriptThread thread2 (functionname2);
thread1.start();
thread2.start();
thread1.wait ();
thread2.wait ();
// optionally fetch return values from the threads and return them
}
Where MyScriptThread is derived from QThread and implements QThread::run() roughly like this:
void MyScriptThread::run () {
QScriptEngine engine;
engine.evaluate (common_script_code);
result = engine.evaluate (the_threads_function);
// the_threads_function passed as a QScriptProgram or QString
}
In general, if documentation says nothing about threading, it is not thread safe.
I would rewrite to use asynchronous requests. Just kick them both off, then wait for them both.