Счётчик с Mutex

К задачам
Средняя
Concurrency

Условие задачи

Создай глобальный счётчик, который увеличивается на 1 в 1000 параллельных горутинах. Твоя задача — защитить доступ к счётчику с помощью sync.Mutex так, чтобы в конце программа вывела строго 1000. Если убрать мьютекс, скорее всего ты получишь меньшее значение из-за гонки данных.

package main

import (
    "fmt"
    "sync"
)

var counter int

func main() {
    var wg sync.WaitGroup
    // TODO: создай мьютекс

    for i := 0; i < 1000; i++ {
        wg.Add(1)
        go func() {
            defer wg.Done()
            // TODO: заблокируй мьютекс, увеличь счётчик, разблокируй
        }()
    }

    wg.Wait()
    fmt.Println("Final counter:", counter)
}
package main

import (
    "fmt"
    "sync"
)

var counter int

func main() {
    var wg sync.WaitGroup
    // TODO: создай мьютекс

    for i := 0; i < 1000; i++ {
        wg.Add(1)
        go func() {
            defer wg.Done()
            // TODO: заблокируй мьютекс, увеличь счётчик, разблокируй
        }()
    }

    wg.Wait()
    fmt.Println("Final counter:", counter)
}

Подсказка

- Используй sync.Mutex - Заблокируй мьютекс перед увеличением счётчика и обязательно освободи его (defer можно). - Без мьютекса будет data race.

Решение

Мы защищаем доступ к общей переменной counter с помощью Mutex, чтобы избежать гонки данных.

package main

import (
    "fmt"
    "sync"
)

var counter int
var mu sync.Mutex

func main() {
    var wg sync.WaitGroup

    for i := 0; i < 1000; i++ {
        wg.Add(1)
        go func() {
            defer wg.Done()
            mu.Lock()
            counter++
            mu.Unlock()
        }()
    }

    wg.Wait()
    fmt.Println("Final counter:", counter)
}
package main

import (
    "fmt"
    "sync"
)

var counter int
var mu sync.Mutex

func main() {
    var wg sync.WaitGroup

    for i := 0; i < 1000; i++ {
        wg.Add(1)
        go func() {
            defer wg.Done()
            mu.Lock()
            counter++
            mu.Unlock()
        }()
    }

    wg.Wait()
    fmt.Println("Final counter:", counter)
}