Summary
In this chapter, we started by looking at light-weight threads and forkIO
. Closely related to this, we looked at mutable references IORef
and MVar
in concurrent settings. Atomic operations on those reference types were quite limited, which is why we next dived into STM
for arbitrarily complex transactions. Then we considered a nice higher-level abstraction over an asynchronous program, the Async API. One of the main benefits of using Async
is easy and automatic cancellation of asynchronous jobs. Finally, we lifted concurrency operations into complex monad stacks.
In the next chapter, we will take a deeper look at the Runtime System, scheduling, and garbage collection. We will look at what options there are to tweak both the compiler and the Runtime System. We will learn how the GHC compilation pipeline works and how to read the intermediate core language that GHC produces just enough to spot possibly missed optimizations.