|
V předchozím příkladu jsme viděli jak jednoduše spravovat stav counterů pomocí atomických operací. Pro více komplikované stavy můžeme použít mutex pro bezpečný přístup k datům z několika gorutin. |
|
![]()
package main
|
|
import (
"fmt"
"sync"
)
|
|
|
|
type Kontejner struct {
mu sync.Mutex
countery map[string]int
}
|
|
Před přístupem ke |
func (k *Kontejner) zvys(jmeno string) {
|
k.mu.Lock()
defer k.mu.Unlock()
k.countery[jmeno]++
}
|
|
|
Všimněte si, že nulová hodnota mutexu je přímo použitelná, takže zde není potřeba žádná inicializace. |
func main() {
k := Kontejner{
|
countery: map[string]int{"a": 0, "b": 0},
}
|
|
var wg sync.WaitGroup
|
|
|
Tato funkce v cyklu zvyšuje pojmenovaný counter. |
zvysuj := func(jmeno string, n int) {
for range n {
k.zvys(jmeno)
}
}
|
|
Spustíme několik gorutin souběžně; všimněte si,
že všechny přistupují ke stejnému |
wg.Go(func() {
zvysuj("a", 10000)
})
|
wg.Go(func() {
zvysuj("a", 10000)
})
|
|
wg.Go(func() {
zvysuj("b", 10000)
})
|
|
|
Počkáme, až gorutiny skončí. |
wg.Wait()
fmt.Println(k.countery)
}
|
|
Spuštění programu ukáže, že se countery aktualizovaly podle očekávání. |
$ go run mutexes.go
map[a:20000 b:10000]
|
|
Dále se podíváme na implementaci tohoto stejného úkolu se správou stavu jenom s pomocí gorutin a kanálů. |
Další příklad: Stavové gorutiny.