“The good news about computers is that they do what you tell them to do. The bad news is that they do what you tell them to do.”
Plus ça change, plus c’est la même chose. Or put another way, everything old is new again. IBM OS/360 introduced threads in 1967. The 1990s brought renewed interest in threads, with POSIX.1c-1995 standardizing their interface. One key factor behind this interest was the development of Linux as an open-source platform for cluster systems. Another factor was the impact of the “power wall” on Moore’s law and integrated circuit design. As a result of this resurgence, threads are now unavoidable as a core abstraction in modern computing.
In this chapter, we will address the following instructional objectives:
Throughout the first part of this book, we referred to processes whenever we were discussing a unit of execution. Specifically, in Processes and Multiprogramming, we described multiprogramming as the technique of dividing time on the CPU among multiple processes. After one process ran for a certain amount of time, the kernel would change the virtual address space to switch the execution context to a different process.
While process context switching provides a robust mechanism for multiprogramming, modern systems require a more efficient approach. Specifically, many programmers write applications or systems programs that achieve concurrency by switching between multiple threads of execution (or, more simply, threads) within a single process. This technique is known as multithreading.
There are many different languages and software libraries available for writing multithreaded code. Some of these options are unique to a single operating system or programming language, while others are more broadly supported. In this and later chapters, we will primarily focus on using the POSIX library (called pthreads), a C library available on all major platforms, though we will also explore some of the benefits of alternative approaches.