使用互斥锁但仍然可以进行并发映射写入

Ray*_* Wu -1 go

我有一个地图,并希望手动进一步分片,简化的代码是

const (
    dictShardNum = 16
    dictShardSize = 1 << 28
)

type shard struct {
    mu sync.Mutex
    m  map[int64]uint32
}

type dict struct {
    shards []shard
}

func newDict() *dict {
   shards := make([]shard, 0, dictShardNum)
   for i := 0; i < dictShardNum; i++ {
      shards = append(shards, shard{ m: make(map[int64]uint32) })
   }
   return &dict{ shards }
}

func (d *dict) insert(n int64) uint32 {
    shardNum := int(n % dictShardNum)
    shard := d.shards[shardNum]
    shard.mu.Lock()
    defer shard.mu.Unlock()

    tempID, ok := shard.m[n]
    if !ok {
        tempID = uint32(len(shard.m) + shardNum*dictShardSize)
        shard.m[n] = tempID   // fatal error: concurrent map writes
    }
    return tempID
}
Run Code Online (Sandbox Code Playgroud)

当我跑到fatal error: concurrent map writes那条线上时,我确实锁定了互斥锁,不知道我的代码有什么问题

pet*_*rSO 5

包同步

import "sync"
Run Code Online (Sandbox Code Playgroud)

键入Mutex

互斥锁是一种互斥锁.互斥锁的零值是解锁的互斥锁.

首次使用后,不得复制互斥锁.


你的代码没有编译!

游乐场:https://play.golang.org/p/6AwS0vOZfeP

25:18: undefined: n
30:24: undefined: n
33:11: undefined: n
Run Code Online (Sandbox Code Playgroud)

如果我v int64改为n int64:

首次使用后,不得复制互斥锁.

$ go vet mutex.go
./mutex.go:26:11: assignment copies lock value to shard: command-line-arguments.shard contains sync.Mutex
$
Run Code Online (Sandbox Code Playgroud)

游乐场:https://play.golang.org/p/jExE-m11ny5

package main

import (
    "sync"
)

const (
    dictShardNum  = 16
    dictShardSize = 1 << 28
)

type shard struct {
    mu sync.Mutex
    m  map[int64]uint32
}

type dict struct {
    shards []shard
}

/// a newDict function

func (d *dict) insert(n int64) uint32 {
    shardNum := int(n % dictShardNum)
    shard := d.shards[shardNum]
    shard.mu.Lock()
    defer shard.mu.Unlock()

    tempID, ok := shard.m[n]
    if !ok {
        tempID = uint32(len(shard.m) + shardNum*dictShardSize)
        shard.m[n] = tempID // fatal error: concurrent map writes
    }
    return tempID
}

func main() {}
Run Code Online (Sandbox Code Playgroud)

指挥兽医

兽医检查Go源代码并报告可疑构造

复制锁

国旗:-copylocks

按值错误传递的锁.