Счётчик с Mutex
Условие задачи
Создай глобальный счётчик, который увеличивается на 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)
}