2 How Programming Languages Model Asynchronous Program Flow In the previous chapter, we covered asynchronous program flow, concurrency, and parallelism in general terms. In this chapter, we'll narrow our scope. Specifically, we'll look into different ways to model and deal with concurrency in programming languages and libraries. It's important to keep in mind that threads, futures, fibers, goroutines, promises, etc. are abstractions that give us a way to model an asynchronous program flow. They have different strengths and weaknesses, but they share a goal of giving programmers an easy-to-use (and importantly, hard to misuse), efficient, and expressive way of creating a program that handles tasks in a non-sequential, and often unpredictable, order. The lack of precise definitions is prevalent here as well; many terms have a name that stems from a concrete implementation at some point in time but has later taken on a more general meaning that encompasses different implementations and varieties of the same thing. We'll first go through a way of grouping different abstractions together based on their similarities before we go on to discuss the pros and cons of each of them. We'll also go through important definitions that we'll use throughout the book and discuss OS threads in quite some detail. The topics we discuss here are quite abstract and complicated so don't feel bad if you don't understand everything immediately. As we progress through the book and you get used to the different terms and techniques by working through some examples, more and more pieces will fall into place. Specifically, the following topics will be covered: Definitions Threads provided by the operating system Green threads/stackfull coroutines/fibers