多线程-释放锁带来的危险
2018-12-07 本文已影响0人
祝方泽
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"]:
- Stop The World方式,每次网络传输时,禁止DeleteAnElem()执行,等所有网络传输结束后,再允许执行DeleteAnElem()。这种方式效率低。
- 在网络传输前,将要传输数据打包成参数,传给SendDataToRemote(),然后SendDataToRemote()与DeleteAnElem()互相独立,可以完全并行执行。
- SendDataToRemote()与DeleteAnElem()依然争抢kv.data,每次SendDataToRemote()获取锁时,先检查kv.data["x"]是否存在。总结一句话:获得锁之后,首先检查全局变量的状态,以防被其它线程修改。