WalzoneInterview Prep
📞 Interviewing soon? Practice with a realistic AI mock phone interview — it calls you, then scores you. First 15 min FREE →

Go · Intermediate · question 37 of 100

How does the ’sync’ package help with concurrent programming in Go?

📕 Buy this interview preparation book: 100 Go questions & answers — PDF + EPUB for $5

The ‘sync‘ package in Go provides synchronization primitives that ease the development and management of concurrent programs. Some of the most commonly used synchronization primitives in the ‘sync‘ package are Mutex, RWMutex, WaitGroup, and Once.

1. Mutex (Mutual Exclusion Lock)

A Mutex provides a mutual exclusion lock that prevents simultaneous access to shared memory by multiple goroutines, ensuring that only one of them can access the resource at a time. This helps avoid race conditions, where execution order or timing affects the behavior and correctness of the code.

For example, consider the following counter being incremented by multiple goroutines:

var counter int

func increment() {
    counter++
}

func main() {
    var wg sync.WaitGroup
    for i := 0; i < 1000; i++ {
        wg.Add(1)
        go func() {
            increment()
            wg.Done()
        }()
    }
    wg.Wait()
    fmt.Println("Counter:", counter)
}

This code might not produce the expected output (Counter: 1000) because of race conditions. To fix this issue, we can use a Mutex:

var (
    counter int
    mu      sync.Mutex
)

func increment() {
    mu.Lock()
    counter++
    mu.Unlock()
}

// The rest of the main function remains the same.

Now, the counter is incremented correctly because the Mutex ensures that only one goroutine can access the shared resource at a time.

2. RWMutex (Read/Write Mutex)

RWMutex is similar to Mutex, but it allows multiple goroutines to read a shared memory simultaneously while still ensuring that write access is mutually exclusive. This can lead to higher performance in cases where there are more reads than writes.

Here’s an example of using RWMutex:

var (
    data    map[string]string
    mu      sync.RWMutex
)

func read(key string) string {
    mu.RLock()
    defer mu.RUnlock()
    return data[key]
}

func write(key, value string) {
    mu.Lock()
    data[key] = value
    mu.Unlock()
}

3. WaitGroup

A WaitGroup is a synchronization primitive that helps you manage a collection of goroutines. It allows your program to wait for a group of goroutines to finish executing before moving forward. This is particularly useful when the main goroutine must wait for other goroutines that may be performing simultaneous tasks (such as making HTTP requests).

Here’s an example of using WaitGroup to wait for multiple goroutines:

func worker(wg *sync.WaitGroup) {
    // Do some work.
    wg.Done()
}

func main() {
    var wg sync.WaitGroup

    for i := 0; i < 10; i++ {
        wg.Add(1)
        go worker(&wg)
    }

    wg.Wait()
    fmt.Println("All goroutines have finished.")
}

4. Once

Once is a synchronization primitive that guarantees a function is called only once, regardless of how many times it’s invoked concurrently.

For example, consider initializing a global variable in a concurrent program:

var (
    data string
    once sync.Once
)

func loadData() {
    data = "Some data"
}

func doSomething() {
    once.Do(loadData)
    // Use the data.
}

func main() {
    var wg sync.WaitGroup

    for i := 0; i < 10; i++ {
        wg.Add(1)
        go func() {
            doSomething()
            wg.Done()
        }()
    }

    wg.Wait()
    fmt.Println("All goroutines have finished.")
}

In this example, even though ‘doSomething()‘ is called multiple times by different goroutines, ‘loadData()‘ is guaranteed to be called only once.

In summary, the ‘sync‘ package makes concurrent programming in Go easier and safer by providing synchronization primitives such as Mutex, RWMutex, WaitGroup, and Once. These primitives help in managing concurrent access to shared memory, waiting for groups of goroutines to finish, and ensuring that a function is called only once.

Reading is step one. Saying it out loud is the interview. Our AI interviewer calls your phone and runs a realistic Go interview — then scores it.
📞 Practice Go — free 15 min
📕 Buy this interview preparation book: 100 Go questions & answers — PDF + EPUB for $5

All 100 Go questions · All topics