Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

QThread vs std::thread

I saw different topics on "pthread vs std::thread" and "QThread vs pthread" but none on "std::thread vs QThread".

I have to program a software to drive a 3D Printer and need to use threads. There will be a thread that will check safety constantly, another to execute the printing process, some for driving each hardware component (movement, jet, ...) separately, etc... The program is developed for Windows with C++11/Qt.

First I wanted to use QThread, but it seems to me that QThread does not allow you to do as many things as std::thread, for instance, while reading "C++ Concurrency in Action" by Anthony Williams, I saw that it was possible to ask a std::thread to execute a function from another thread by doing something like std::thread t1(&Class::function, this, ...); which does not seem to be possible with QThread.

The mechanism I would like to have most is a way of saying if I want a function to be executed in the current thread or in another thread.

Which one would you choose to do that and why ?

like image 211
ElevenJune Avatar asked Oct 27 '16 12:10

ElevenJune


People also ask

Why use QThread?

Using QThread to Prevent Freezing GUIs. A common use for threads in a GUI application is to offload long-running tasks to worker threads so that the GUI remains responsive to the user's interactions. In PyQt, you use QThread to create and manage worker threads.

Does std :: thread use pthreads?

The std::thread library is implemented on top of pthreads in an environment supporting pthreads (for example: libstdc++).


2 Answers

QThread is not just a thread, it is also a thread manager. If you want your thread to play Qt, then QThread is the way to go. Qt is event driven, as is most of modern programming. That's a little more complex and flexible than "make a thread run a function".

In Qt, you'd typically create a worker together with a QThread, move the worker to that thread, then every function invoked by the event system for that worker object will be executed in the thread the worker object has affinity to.

So you can encapsulate your functionality in different worker object, say SafetyChecker, Printer, ServoDriver, JetDriver and so on, create an instance of each, move it to a dedicated thread and you are set. You still can invoke functions that would "block" instead of using fine grained events, and use atomics or mutexes to do inter-thread synchronization. There is nothing wrong with that, as long as you don't block the main/gui thread.

You would probably not want to do your printer code event driven, since in a multithreaded scenario that would involve queued connections, which are marginally slower than direct connections or even virtual dispatch. So much so that if you make your multithreading too fine grained, you are likely to actually experience a huge performance hit.

That being said, using Qt's non-gui stuff has its own merits, it will allow you to make a cleaner and more flexible design much easier, and you will still get the benefits of multithreading if you implement things properly. You can still use an event driven approach to manage the whole thing, it will be significantly easier than using only std::thread, which is a much lower level construct. You can use event driven approach to setting up, configuring, monitoring and managing the design, while the critical parts can be executed in blocking functions in auxiliary threads to achieve fine grained control at the lowest possible synchronization overhead.

To clarify - the answer does not focus on async task execution, because the other two answers already do, and because as I mentioned in the comments, async tasks are not really intended for control applications. They are suited to the execution of small tasks, which still take more time than you'd want to block the main thread for. As a recommended guideline, everything that takes more than 25 msec is preferable to be executed async. Whereas printing is something that may take minutes or even hours, and imply continuously running control functions, in parallel and using synchronization. Async tasks won't give you the performance, latency and order guarantees for control applications.

like image 95
dtech Avatar answered Oct 04 '22 00:10

dtech


QThread is nice if you want to integrate the thread into the Qt system (like having to emit signals or connect to certain slots)

Though the layout of QThread is still made so it works with "old" c++. You have to create a class and all this overhead (code and typing wise) just for running in a thread.

If you just simply want to start a thread I think c++11 std::thread is less verbose/code you have to write. You can just use a lambda or function pointer and can give as many arguments as you want. So for simple threading I would suggest the c++11 threads over the QThreads.

Ofcourse it can be a matter of opinion which of those you prefer.


Though Qt has several different high level thread objects C++ does not. You may want to look into these if you need some of those instead of a basic thread or maybe you don't really need a basic thread at all but those suit you better.

Like a QThreadPool or simply a QTimer if you need to wait for things. Here is some readup about the alternatives in Qt to a bare thread.

QConcurrent also comes more close to c++11 future and async for example and has also optional threadpools where it can run.

like image 43
Hayt Avatar answered Oct 03 '22 23:10

Hayt