多线程-释放锁带来的危险

type KV struct {
    mu Mutex
    data map[string]string
}

func (kv *KV) SendData() {
    for {
        sleep(1s)
        for _, host := hostList {
            go SendDataToRemote() {
                kv.mu.lock()
                // send kv.data['x'] to remote
                kv.mu.unlock()
            }
        }
    }
}

func (kv *KV) DeleteAnElem(k string) {
    kv.mu.lock()
    // delete data[k]
    kv.mu.unlock()
}

func main() {
    kv := make(KV)
    go kv.SendData()
    go kv.DeleteAnElem("x")
}

我想到有三种方案保护kv.data["x"]:

  1. Stop The World方式,每次网络传输时,禁止DeleteAnElem()执行,等所有网络传输结束后,再允许执行DeleteAnElem()。这种方式效率低。
  2. 在网络传输前,将要传输数据打包成参数,传给SendDataToRemote(),然后SendDataToRemote()与DeleteAnElem()互相独立,可以完全并行执行。
  3. SendDataToRemote()与DeleteAnElem()依然争抢kv.data,每次SendDataToRemote()获取锁时,先检查kv.data["x"]是否存在。总结一句话:获得锁之后,首先检查全局变量的状态,以防被其它线程修改

你可能感兴趣的:(多线程-释放锁带来的危险)