- Артикул:00-01120631
- Автор: James Cutajar
- ISBN: 9781633438385
- Обложка: Мягкая обложка
- Издательство: Manning Publications Co. (все книги издательства)
- Город: USA
- Страниц: 325
- Год: 2024
- Вес: 814 г
Издание на английском языке
This book is a practical guide to the concepts and techniques of concurrent programming needed to build highly efficient and reliable systems. You'll learn how to recognize and avoid problems such as deadlocks and race conditions, and gain proven solutions for debugging multithreaded applications. The author shares his years of experience on the cutting edge of development, describing real-world scenarios encountered in interviews and in his professional work. This book is intended for developers of all skill levels who want to master the complex yet in-demand field of concurrent programming and learn to write safe, efficient, and scalable code.
Content
Preface
Acknowledgments
About this book
About the author
About the cover illustration
Part 1. Foundations
1. Stepping into concurrent programming
1.1. About concurrency
1.2. Interacting with a concurrent world
1.3. Increasing throughput
1.4. Improving responsiveness
1.5. Programming concurrency in Go
Goroutines at a glance
Modeling concurrency with CSP and primitives
Building our own concurrency tools
1.6. Scaling performance
Amdahl's law
Gustafson's law
Dealing with threads
2.1. Multiprocessing in operating systems
2.2. Abstracting concurrency with processes and threads
Concurrency with processes
Creating processes
Using multiprocessing for common tasks
Concurrency with threads
A multithreaded application in practice
Using multiple processes and threads together
2.3. What's so special about goroutines?
Creating goroutines
Implementing goroutines in the user space
Scheduling goroutines
2.4. Concurrency versus parallelism
2.5. Exercises
Thread communication using memory sharing
3.1. Sharing memory
3.2. Memory sharing in practice
Sharing a variable between goroutines
Escape analysis
Updating shared variables from multiple goroutines
3.3. Race conditions
Stingy and Spendy: Creating a race condition
Yielding execution does not help with race conditions
Proper synchronization and communication eliminate race conditions
The Go race detector
3.4. Exercises
Synchronization with mutexes
4.1. Protecting critical sections with mutexes
How do we use mutexes?
Mutexes and sequential processing
Non-blocking mutex locks
4.2. Improving performance with readers-writer mutexes
Go's readers-writer imulex
Building our own read-preferred readers-writer imutex
4.3. Exercises
Condition variables and semaphores
5.1. Condition variables
Combining mutexes with condition variables 90
Missing the signal
Synchronizing multiple goroutines with waits and broadcasts
Revisiting readers-writer locks using condition variables
5.2. Counting semaphores
What's a semaphore?
Building a semaphore
Never miss a signal with semaphores
5.3. Exercises
Synchronizing with waitgroups and barriers
6.1. Waitgroups in Go
Waiting for tasks to complete with waitgroups
Creating a waitgroup type using semaphores
Changing the size of our waitgroup while waiting
Building a more flexible waitgroup
6.2. Barriers
What is a barrier?
Implementing a barrier in Go
Concurrent matrix multiplication using barriers
6.3. Exercises
Part 2. Message passing
Communication using message passing
7.1. Passing messages
Passing messages with channels
Buffering messages with channels
Assigning a direction to channels
Closing channels
Receiving function results with channels
7.2. Implementing channels
Creating a channel with semaphores
Implementing the Send function in our channel
Implementing the Receive function in our channel
7.3. Exercises
Selecting channels
8.1. Combining multiple channels
Reading from multiple channels
Using select for non-blocking channel operations
Performing concurrent computations on the default case
Timing out on channels
Writing to channels with select
Disabling select cases with nil channels
8.2. Choosing between message passing and memory sharing
Balancing code simplicity
Designing tightly versus loosely coupled systems
Optimizing memory consumption
Communicating efficiently
8.3. Exercises
Programming with channels
9.1. Communicating sequential processes
Avoiding interference with immutability
Concurrent programming with CSP
9.2. Reusing common patterns with channels
Quitting channels
Pipelining with channels and goroutines
Fanning in and out
Flushing results on close
Broadcasting to multiple goroutines
Closing channels after a condition
Adopting channels as first-class objects
9.3. Exercises
Part 3. More concurrency
Concurrency patterns
10.1. Decomposing programs
Task decomposition
Data decomposition
Thinking about granularity
10.2. Concurrency implementation patterns
Loop-level parallelism
The fork/join pattern
Using worker pools
Pipelining
Pipelining properties
10.3. Exercises
Avoiding deadlocks
11.1. Identifying deadlocks
Picturing deadlocks with resource allocation graphs
Deadlocking in a ledger
11.2. Dealing with deadlocks
Detecting deadlocks
Avoiding deadlocks
Preventing deadlocks
11.3. Deadlocking with channels
11.4. Exercises
Atomics, spin locks, and futexes
12.1. Lock-free synchronization with atomic variables
Sharing variables with atomic numbers
Performance penalty when using atomics
Counting using atomic numbers
12.2. Implementing a mutex with spin locks
Comparing and swapping
Building a mutex
12.3. Improving on spin locking
Locking with futexes
Reducing system calls
Go's mutex implementation
12.4. Exercises
Index

