liveBook · Manning

Critical region

As explained in Learn Concurrent Programming with Go

A critical section is a region of code that accesses shared state and requires coordination to prevent conflicting concurrent access.

A critical region, also called a critical section, is the part of concurrent code that uses shared state and must run without interference from another execution. If goroutines overlap there, a read-modify-write operation such as changing a shared bank balance can produce unpredictable results—a race condition. section 3.3.1 section 3.5

A shared balance can drift

Two goroutines repeatedly add and subtract $10 from the same balance. Although the intended final balance is $100, separate runs can finish with radically different values because each update consists of multiple instructions that may interleave. The Stingy and Spendy listing and race-condition figure make the conflicting execution order visible. section 3.3.1

Protect a critical region with a mutex: lock immediately before accessing the shared resource, execute the protected work, then unlock. Only one goroutine can acquire the lock; contenders wait until it is released. In Go, `sync.Mutex` supplies `Lock()` and `Unlock()` for these boundaries. section 4.1.1 section 4.1

Listing 4.1 Stingy’s and Spendy’s functions using a mutex
package main

import (
    "fmt"
    "sync"
    "time"
)

func stingy(money *int, mutex *sync.Mutex) {    #1
    for i := 0; i < 1000000; i++ {
        mutex.Lock()                            #2
        *money += 10
        mutex.Unlock()                          #3
    }
    fmt.Println("Stingy Done")
}

func spendy(money *int, mutex *sync.Mutex) {    #1
    for i := 0; i < 1000000; i++ {
        mutex.Lock()                            #2
        *money -= 10
        mutex.Unlock()                          #3
    }
    fmt.Println("Spendy Done")
}
#1 Accepts a pointer to the shared mutex struct
#2 Locks the mutex before entering the critical section
#3 Unlocks after exiting the critical section

The paired functions show the smallest useful boundary: lock around each shared balance update, then unlock before continuing. section 4.1.1

Choose boundaries around the resource rather than around an entire goroutine:

  • Keep unrelated, lengthy work outside the lock. Locking a whole document download serializes work that could safely run concurrently. section 4.1.2
  • Protect both writes and reads of the shared value when they can conflict with concurrent updates. section 4.1.1
  • Do not use scheduler yielding as synchronization. `runtime.Gosched()` can alter timing but cannot guarantee that another execution will not interfere. section 3.3.2
  • Consider readers–writer mutexes for read-heavy shared resources: concurrent readers may proceed, while a writer receives exclusive access. section 4.4

A critical region should be as small as correctness permits, but not smaller than the operations that must remain coordinated. Excessive locking and unlocking has a cost; holding a lock too long turns concurrent execution into sequential execution. When shared-memory protection makes data flow hard to follow, message passing can offer a simpler alternative. section 4.1.2 section 8.2.1

How Learn Concurrent Programming with Go covers it

How deep it goes
Defines critical sections, traces an interleaving race, and details mutex boundaries and lock-scope performance trade-offs.
Examples
Uses Stingy and Spendy’s shared bank balance and a concurrent web-document letter-frequency counter.
What it assumes
Introduces critical sections through goroutines and shared variables without assuming synchronization terminology.
What you can do after
Apply it via Go’s sync.Mutex by locating shared resources and placing Lock and Unlock around their coordinated access.
How it connects
Connects shared memory, race conditions, atomic operations, mutexes, readers–writer mutexes, and message passing.

Also explained in

Compare how 9 books explain critical region →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Learn Concurrent Programming with Go. The section links point to the parts of the book it draws on.