Multithreading with Qt How to leverage the modern C++11 threading capabilities in your Qt application
This talk introduces you to the fundamentals of threading in Qt. We will discuss how threads, QObjects and events interact together; how a thread affinity of a QObject has a play in signals and slots connections; and how you can leverage the modern C++11 threading capabilities in your Qt application.
Cross-platform thread support was introduced in Qt 2.2, released in 2000, ages before it finally got standardized by C++11. This support has allowed developers using Qt to successfully build countless multithreaded applications, running natively on many operating systems: Windows, Linux, OS X, QNX, iO S, Android, and so on.
Across the span of four major versions Qt’s threading facilities have been greatly expanded and improved. Following Qt’s evolution across the years, a number of “design patterns” have emerged, in order to allow developers to use these facilities to the maximum extent, and not fall into any of the countless traps of multithreaded programming.
In this talk I will discuss the basics of thread support in Qt, starting from QThread, the central class in Qt that manages a thread. I will then focus on the interactions between QObjects, QThreads and thread-local event loops, and how all of this plays a role into the cross-thread signals and slots. The most common pitfalls will be analyzed and discussed here.
I will then show how to “mix and match” Qt and C++11/14 threading and synchronization primitives, and what degree of support one can expect when moving away from Qt’s constructs in favour of the standard C++ ones.
Thanks for the great talk. This should be mandatory to see for everyone doing threading in Qt 🙂
Isn’t the problem described at 0:43:23 (i.e. “Producer start emitting signals before it is connected to Consumer”) the same as what happens with QNetworkAccessManager::get()? I’ve seen this pattern a ton of times, i.e. QNetworkAccessManager::get() return a QNetworkReply*, and subsequently we call QObject::connect() to connect reply’s finished/error signals, but at that time the request has been already sent. Of course a network request, especially over the internet, is way slower than the Qt event loops, but isn’t this an unhealthy assumption? Suppose there is an underlying new feature of QNetworkAccessManager that will route a request and provide a reply in the same method (e.g. via some hook) bypassing network connections entirely; in this case would we face the described problem.
You are right that, if QNAM wasn’t properly designed, there might be a race between the connection to the reply’s signals and the reply data itself arriving. Luckily, QNAM is properly designed 🙂 When one submits a request to QNAM, its processing is event-driven and will start only when returning to the event loop. This means that it’s perfectly safe to connect to the signals *before* returning to the event loop, as nothing has happened yet.