Синхронизация goroutine через sync.WaitGroup

WaitGroup решит ожидание, но не гонку между тремя писателями map. Нужен также mutex для самих записей.

Короткий ответ

Что ответить на собеседовании

WaitGroup решит ожидание, но не гонку между тремя писателями map. Нужен также mutex для самих записей.

Подробный разбор

Ответ с пояснениями

Условие

В приведённом примере несколько горутин одновременно изменяют одну и ту же карту map[int]bool, что приводит к гонке данных. Чтобы гарантировать, что все изменения завершатся до того, как мы попытаемся прочитать значение из карты, необходимо воспользоваться sync.WaitGroup. Нужно добавить вызов Add() перед запуском горутин, вызвать Done() в конце каждой горутины и выполнить Wait() перед чтением карты. Укажите места вставки этих методов.

package main

import (
    "fmt"
    "time"
)

func main() {
    data := make(map[int]bool)

    go func() {
        data[1] = true
    }()
    go func() {
        data[1] = true
    }()
    go func() {
        data[1] = false
    }()

    time.Sleep(1 * time.Second)
    fmt.Printf("%v", data[1])
}

Ответ

WaitGroup решит ожидание, но не гонку между тремя писателями map. Нужен также mutex для самих записей.

Исправленный вариант:

package main

import (
    "fmt"
    "sync"
)

func main() {
    data := make(map[int]bool)
    var wg sync.WaitGroup
    var mu sync.Mutex
    for _, value := range []bool{true, true, false} {
        wg.Add(1)
        go func(value bool) {
            defer wg.Done()
            mu.Lock()
            data[1] = value
            mu.Unlock()
        }(value)
    }
    wg.Wait()
    fmt.Printf("%v", data[1])
}

Add вызывается до go, Done — внутри, Wait — перед чтением. После Wait писателей уже нет, поэтому финальное чтение не требует блокировки. Итог true или false зависит от последней записи: синхронизация устраняет гонку, но не задаёт порядок.

ИИ-помощник для собеседований

Хочешь уверенно проходить собеседования?

Попробуй ИИ-помощник для собеседований: слышит вас и собеседника, анализирует экран, подсказывает ответы в реальном времени, работает без VPN и не попадает в захват экрана.

Подробнее