When goroutines access or modify the same data, their operations can interfere and cause data-integrity errors. A mutex makes access exclusive: a goroutine locks the shared resource, uses it, and unlocks it so another can proceed. section 5.2.2
In Go, use sync.Mutex to protect shared data. A concurrent word-counting program can race while updating a shared map; Go’s --race flag helps identify the conflicting accesses. section 5.2.2
Listing 5.5 Word counter with locks
package main
import (
// Same as before…
"sync"
)
func main() {
var wg sync.WaitGroup
w := newWords()
if len(os.Args) < 2 {
fmt.Println("no files provided")
os.Exit(1)
}
for _, f := range os.Args[1:] {
wg.Add(1)
go func(file string) {
if err := tallyWords(file, w); err != nil {
fmt.Println(err.Error())
}
wg.Done()
}(f)
}
wg.Wait()
fmt.Println("Words that appear more than once:")
w.Lock() #1
defer w.Unlock()
for word, count := range w.found {
if count > 1 {
fmt.Printf("%s: %d\n", word, count)
}
}
}
type words struct {
sync.Mutex #2
found map[string]int
}
func newWords() *words {
return &words{found: map[string]int{}}
}
func (w *words) add(word string) {
w.Lock() #3
defer w.Unlock()
count, ok := w.found[word]
if !ok {
w.found[word] = 1
return
}
w.found[word] = count + 1
}
func tallyWords(filename string, dict *words) error {
// Unchanged from before
}
See the word-counter example using locks to protect shared data. section 5.2.2

















