In this chapter, we covered a lot of stuff, but concurrency is one of most important and, sadly, one of the most difficult and error-prone topics in programming.
We started with the basics, namely with what threads, mutexes, and atomics are. Then we learned the unfortunate fact that the use of mutexes can lead to several problems such as: deadlocks, livelocks, starvation, priority inversion, convoying, and false sharing. Fortunately, these problems can be avoided with some care. We then progressed to evaluating the performance costs of using threads and mutexes and of their alternative, namely lock-free data structures. In the next section, we learned what thread support classes Qt provides and how they integrate with its signal-slot mechanism. After that, we proceeded to multithreading optimization techniques—first, we learned how to decrease thread construction...