parallel_programming.htm
Notes on Parallel Programming
Introduction
Race Condition: A race condition occurs in Go when two or more goroutines try to access and modify the same data at the same time. This can lead to data corruption , inconsistent states, or crashes.
Atomicity: within the context it operates it is indivisible or uninterruptible. Atomicity is important because if something is atomic, implicitly it is safe within concurrent contexts. This allow us to run safe parallel programs.
Deadlock: concurrent parts of the program are waiting for one another.
Types of deadlock:
- Mutual exclusion - process p1 holds exclusive rights for p2
- Wait for condition - hold a resource and wait for an additional resource
- No preemption - resource is held by a concurrent process and it can only be released by that process
- Circular wait - p1 is waiting for p2 but p2 is waiting for p1
Livelock: the program runs concurrent ops but these ops don't move the code forward.
A common reason livelocks are written: two or more concurrent processes attempting to prevent a deadlock without coordination.
Finding a balance between polite and greedy locking:
- If you utilize memory access synchronization, you’ll have to find a balance between preferring coarse-grained synchronization for performance, and fine-grained syn‐ chronization for fairness. When it comes time to performance tune your application, to start with, I highly recommend you constrain memory access synchronization only to critical sections;
When exposing functions, methods, and variables in problem spaces that involve concurrency, do your colleagues and future self a favor: err on the side of verbose comments, and try and cover these three aspects.
• Who is responsible for the concurrency? • How is the problem space mapped onto concurrency primitives? • Who is responsible for the synchronization?
Communicating Processes
Concurrency is a property of the code; parallelism is a property of the running program.
The first is that we do not write parallel code, only concurrent code that we hope will be run in parallel. Once again, parallelism is a property of the runtime of our program, not the code.
Go created the primitives of channels based on Hoare's research on input/output of a program being an underexplored part of computer science.
One of Go’s mottos is “Share memory by communicating, don’t communicate by shar‐ ing memory. That said, Go does provide traditional locking mechanisms in the sync package. Most locking issues can be solved using either channels or traditional locks. So which should you use? Use whichever is most expressive and/or most simple.
Concurrency Primitives
func main()