The role of the operating system 13 In an effort to make the definitions as distinct as possible, we'll define these terms more narrowly than you' d normally see. However, just be aware that we can't please everyone and we do this for our own sake of making the subject easier to understand. On the other hand, if you fancy heated internet debates, this is a good place to start. Just claim someone else's definition of concurrent is 100 % wrong or that yours is 100 % correct, and off you go. For the sake of this book, we'll stick to this definition: asynchronous programming is the way a programming language or library abstracts over concurrent operations, and how we as users of a language or library use that abstraction to execute tasks concurrently. The operating system already has an existing abstraction that covers this, called threads. Using OS threads to handle asynchrony is often referred to as multithreaded programming. To avoid confusion, we'll not refer to using OS threads directly as asynchronous programming, even though it solves the same problem. Given that asynchronous programming is now scoped to be about abstractions over concurrent or parallel operations in a language or library, it's also easier to understand that it's just as relevant on embedded systems without an operating system as it is for programs that target a complex system with an advanced operating system. The definition itself does not imply any specific implementation even though we'll look at a few popular ones throughout this book. If this still sounds complicated, I understand. Just sitting and reflecting on concurrency is difficult, but if we try to keep these thoughts in the back of our heads when we work with async code I promise it will get less and less confusing. The role of the operating system The operating system (OS) stands in the center of everything we do as programmers (well, unless you're writing an operating system or working in the embedded realm), so there is no way for us to discuss any kind of fundamentals in programming without talking about operating systems in a bit of detail. Concurrency from the operating system's perspective This ties into what I talked about earlier when I said that concurrency needs to be talked about within a reference frame, and I explained that the OS might stop and start your process at any time. What we call synchronous code is, in most cases, code that appears synchronous to us as programmers. Neither the OS nor the CPU lives in a fully synchronous world. Operating systems use preemptive multitasking and as long as the operating system you're running is preemptively scheduling processes, you won't have a guarantee that your code runs instruction by instruction without interruption. The operating system will make sure that all important processes get some time from the CPU to make progress.