Go 使用sync.Mutex片段的适当方法

Go 使用sync.Mutex片段的适当方法,go,mutex,Go,Mutex,我最近完成了golang之旅,并尝试使用sync.Mutex复制一个练习来增加地图键的值。我使用[]sync.mutex切片为每个键创建了一个互斥体。当我运行代码时,我得到一条并发映射写入的错误消息。我在下面的代码中做错了什么 package main import ( "fmt" "sync" ) type SafeUpdate struct { s map[string]int m []sync.Mutex } func (su *SafeUpdate)

我最近完成了golang之旅,并尝试使用sync.Mutex复制一个练习来增加地图键的值。我使用
[]sync.mutex
切片为每个键创建了一个互斥体。当我运行代码时,我得到一条并发映射写入的错误消息。我在下面的代码中做错了什么

package main

import (
    "fmt"
    "sync"
)

type SafeUpdate struct {
    s map[string]int
    m []sync.Mutex
}

func (su *SafeUpdate) Inc (key string, idx int, wg *sync.WaitGroup) {
    defer wg.Done()

    su.m[idx].Lock()
    defer su.m[idx].Unlock()

    su.s[key]++
}

func main() {
    su := SafeUpdate{s: make(map[string]int), m : make([]sync.Mutex, 3)}
    keymap := map[int]string{0: "zero", 1: "one", 2: "two"}
    wg := new(sync.WaitGroup)

    for i := 0; i < 1000; i++ {
        wg.Add(1)
        go su.Inc(keymap[i%3], i%3, wg)
    }
    wg.Wait()
    fmt.Println(su)
}

您提供的消息中没有错误。
su.s[key]++
--此表达式同时运行,必须同步。如果你想改变地图-你必须阻止只有一个goroutine在做它。@zerkms我明白我做错了什么。我不应将地图视为由键的不同部分组成,而应将地图视为一个整体。感谢您提供的消息中没有错误。
su.s[key]++
--此表达式同时运行,必须同步。如果你想改变地图-你必须阻止只有一个goroutine在做它。@zerkms我明白我做错了什么。我不应将地图视为由键的不同部分组成,而应将地图视为一个整体。谢谢
fatal error: concurrent map writes

goroutine 38 [running]:
runtime.throw(0x4c3a62, 0x15)
    /usr/local/go/src/runtime/panic.go:1116 +0x72 fp=0xc0000c46f0 sp=0xc0000c46c0 pc=0x42f2d2
runtime.mapassign_faststr(0x4a7ae0, 0xc000098150, 0x4c11c6, 0x3, 0x0)
    /usr/local/go/src/runtime/map_faststr.go:211 +0x3f7 fp=0xc0000c4758 sp=0xc0000c46f0 pc=0x4107e7
main.(*SafeUpdate).Inc(0xc0000ac020, 0x4c11c6, 0x3, 0x2, 0xc0000b6010)
    /home/afrozalm/Project/goLang/keyMutex.go:19 +0xe6 fp=0xc0000c47b8 sp=0xc0000c4758 pc=0x491cc6
runtime.goexit()
    /usr/local/go/src/runtime/asm_amd64.s:1373 +0x1 fp=0xc0000c47c0 sp=0xc0000c47b8 pc=0x45be81
created by main.main
    /home/afrozalm/Project/goLang/keyMutex.go:29 +0x2be

.
.
.