The thread library – an introduction
The main library to create and manage threads in C++ is the thread library. First, let’s go through a recap about threads. Then we will dive into what the thread library offers.
What are threads? Let’s do a recap
The purpose of threads is to execute multiple simultaneous tasks in a process.
As we have seen in the previous chapter, a thread has its own stack, local data, and CPU registers such as Instruction Pointer (IP) and Stack Pointer (SP), but shares the address space and virtual memory of its parent process.
In the user space, we can differentiate between native threads and lightweight or virtual threads. Native threads are the ones created by the OS when using some kernel APIs. The C++ thread objects create and manage these types of threads. On the other hand, lightweight threads are like native threads, except that they are emulated by a runtime or library. In C++, coroutines belong to this group. As described in the previous chapter, lightweight threads have faster context switching than native threads. Also, multiple lightweight threads can run in the same native thread and can be much smaller than native threads.
In this chapter, we will start learning about native threads. In Chapter 8, we will learn about lightweight threads in the form of coroutines.
The C++ thread library
In C++, threads allow multiple functions to run concurrently. The thread
class defines a type-safe interface to a native thread. This class is defined in the std::thread
library, in the <thread>
header file in the Standard Template Library (STL). It is available from C++11 onward.
Before the inclusion of the thread library in the C++ STL, developers used platform-specific libraries such as the POSIX thread (pthread
) library in Unix or Linux OSs, the C Runtime (CRT) and Win32 libraries for Windows NT and CE systems, or third-party libraries such as Boost.Threads
. In this book, we will only use modern C++ features. As <thread>
is available and provides a portable abstraction on top of platform-specific mechanisms, none of these libraries will be used or explained. In Chapter 9, we will introduce Boost.Asio
, and in Chapter 10, Boost.Cobalt
. Both libraries provide advanced frameworks to deal with asynchronous I/O operations and coroutines.
Now it’s time to learn about the different thread operations.