Concurrency and Asynchronous Programming: a Detailed Overview 14 Note This is not as simple when we're talking about modern machines with 4, 6, 8, or 12 physical cores, since you might actually execute code on one of the CPUs uninterrupted if the system is under very little load. The important part here is that you can't know for sure and there is no guarantee that your code will be left to run uninterrupted. Teaming up with the operating system When you make a web request, you're not asking the CPU or the network card to do something for you-you're asking the operating system to talk to the network card for you. There is no way for you as a programmer to make your system optimally efficient without playing to the strengths of the operating system. Y ou basically don't have access to the hardware directly. You must remember that the operating system is an abstraction over the hardware. However, this also means that to understand everything from the ground up, you'll also need to know how your operating system handles these tasks. To be able to work with the operating system, you'll need to know how you can communicate with it, and that's exactly what we're going to go through next. Communicating with the operating system Communication with an operating system happens through what we call a system call (syscall ). We need to know how to make system calls and understand why it's so important for us when we want to cooperate and communicate with the operating system. We also need to understand how the basic abstractions we use every day use system calls behind the scenes. We'll have a detailed walkthrough in Chapter 3, so we'll keep this brief for now. A system call uses a public API that the operating system provides so that programs we write in 'userland' can communicate with the OS. Most of the time, these calls are abstracted away for us as programmers by the language or the runtime we use. Now, a syscall is an example of something that is unique to the kernel you're communicating with, but the UNIX family of kernels has many similarities. UNIX systems expose this through libc. Windows, on the other hand, uses its own API, often referred to as Win API, and it can operate radically differently from how the UNIX-based systems operate. Most often, though, there is a way to achieve the same things. In terms of functionality, you might not notice a big difference but as we'll see later, and especially when we dig into how epoll, kqueue, and IOCP work, they can differ a lot in how this functionality is implemented.