Comparing C++ and Qt Thread Tools

This table compares the primary Qt classes to their corresponding primary C++ classes in the std namespace. Examples in Barlas' book employ Qt; we will be using the C++ classes. You may find it useful to refer to this page while studying various examples in the book.

While several methods of these classes are shown, there are many others not shown. For definitive descriptions of all methods, consult the appropriate documentation. A good reference for the C++ classes is www.cplusplus.com/reference/multithreading. Documentation for the Qt classes is currently located at https://doc.qt.io/.

QtC++Comments
Create and instantiate a subclass of QThread; then use instance methods including:
  • start (calls run)
  • wait()
  • run (must be implemented in subclass; typically only called from start)
Instantiate std::thread; the thread starts as soon as the constructor is invoked; then:
  • join()
This functionality is for launching and managing individual threads via instances of a thread class.
Initiation:
Qt: Subclass QThread; implement run; thread launched when start method called. Passing data to the thread is handled by ensuring that instance variables of the QThread subclass have been set before the start method is called.

C++: Thread launched as soon as constructor executed. Passing data to the thread is handled by listing the parameters following the method parameter passed to the std::thread constructor.

Suspending execution of parent until child finishes:
Qt: invoke wait method

C++: invoke join method

QtConcurrent::run & QFuture<T>
    void waitForFinished()
    T result()
std::async & std::future<T>
    void wait()
    T get()
This functionality allows programs to retrieve results generated by code running on individual threads. (This essentially allows a "thread return value" analogous to a "function return value".)
QMutex
    void lock()
    void unlock()
    bool tryLock()
std::mutex
    void lock()
    void unlock()
    bool try_lock()
A mutex is a binary semaphore
QSemaphore
    void acquire()
    void acquire(int n)
    void release()
    void release(int n)
    void tryAcquire()
    void tryAcquire(int n)
Counting semaphores are not currently available in C++. Here is a partial implementation of Qt's counting semaphores using C++ functionality: Semaphore.h. Counting semaphore
QMutexLocker
    QMutexLocker(&aMutex)
std::unique_lock<std::mutex>
    std::unique_lock<std::mutex>(aMutex)
This is a convenience class that manages locking and unlocking of the given mutex. In addition to simplifying your code for most basic uses of mutex objects, it guarantees that resources will be unlocked even if an exception is thrown.
QWaitCondition
    void wait(&aMutex)
    void wakeOne()
    void wakeAll()
std::condition_variable
    void wait(aUniqueLock)
    void notify_one()
    void notify_all()
Note that the wait method of QWaitCondition takes a pointer to a QMutex, whereas the wait method of std::condition_variable takes a reference to the std::unique_lock that owns the mutex.
QAtomicInt
QAtomicPointer

std::atomic<int>

in general:

  • std::atomic<some-primitive-type-or-pointer>
  • pre-defined instances of this template type: std::atomic_bool, std::atomic_int, etc.
Primitives that guarantee that one thread at a time has access to them.
barrier: Not currently in Qt barrier: Not currently in C++ thread classes

But here is a barrier implementation using C++ functionality. While this works when used correctly, it is easy for programmers to break it through incorrect use of the "barrier" method; see the "known design limitation" comments: Barrier.h.

A tool that imposes a synchronization point on n threads.