~/Go Goroutine Sequencing with sync Cond Example

Jul 27, 2025


This Go code demonstrates orchestrating sequential goroutine execution using a sync.Cond and sync.Mutex. Goroutines proceed in strict order, each waiting for its turn using the condition variable and signaling the next when done.

Key points:

Example output:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
Goroutine 2 waiting...
Goroutine 3 waiting...
Goroutine 5 waiting...
Goroutine 4 waiting...
Goroutine 1 is running its task
Goroutine 1 finished its task
Goroutine 1 signaling next goroutine
Goroutine 2 woke up, checking condition
Goroutine 2 is running its task
...
All goroutines have completed

This pattern guarantees the goroutines run one after another, not concurrently, which is useful for scenarios needing ordered execution. For further reading on Go synchronization, see Go Blog: Share Memory by Communicating.

Example code block for reference:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
import (
    "fmt"
    "sync"
    "time"
)

func main() {
    var mu sync.Mutex
    cond := sync.NewCond(&mu)
    currentGoroutine := 1
    totalGoroutines := 5
    var wg sync.WaitGroup
    wg.Add(totalGoroutines)

    for i := 1; i <= totalGoroutines; i++ {
        go func(id int) {
            defer wg.Done()
            mu.Lock()
            defer mu.Unlock()
            for currentGoroutine != id {
                cond.Wait()
            }
            fmt.Printf("Goroutine %d is running its task\n", id)
            time.Sleep(time.Second)
            currentGoroutine++
            cond.Signal()
        }(i)
    }
    wg.Wait()
    fmt.Println("All goroutines have completed")
}

For alternatives, consider using channels for simpler sequencing in many cases.

Tags: [go] [concurrency] [sync]