As you may have concluded by reading this book, writing concurrent and distributed programs is not easy. Ensuring program correctness, scalability, and fault-tolerance is harder than in a sequential program. Here, we recall some of the reasons for this:
First of all, most concurrent and distributed computations are, by their nature, non-deterministic. This non-determinism is not a consequence of poor programming abstractions, but is inherent in systems that need to react to external events.
Data races are a basic characteristic of most shared-memory multicore systems. Combined with inherent non-determinism, these lead to subtle bugs that are hard to detect or reproduce.
When it comes to distributed computing, things get even more complicated. Random faults, network outages, or interruptions, present in distributed programming, compromise correctness and robustness of distributed systems.
Furthermore, shared-memory programs do not work in distributed environments, and existing...