i4box’s Blog

What, Why, How ?

Data Race学习

最近准备将gopush代码中rpc模块提出来复用一下,看到这样段代码,很是不解:

tmpClients := make(map[string]*WeightRpc, len(r.Clients))
for addr, client := range r.Clients {
    if client == nil {
        continue
    }
    tmpClients[addr] = client
    if client.Addr == retryAddr {
        client.Client = rpcTmp
    }
}
// atomic update clients
r.Clients = tmpClients

代码中需要更新map[string]*WeightRpc这个Clients(该Clients只被这一个goroutine修改,其他多个goroutine回去读),作者先copy一个临时的map,进行修改后,直接赋值给原map,并注释上这样是原子更新。

如果不解,可以看看作者的说明:issue

关于data race详细介绍,请看下面几篇文章

《谈谈go语言编程的并发安全》

Atomic vs. Non-Atomic Operations

Benign data races: what could possibly go wrong?

Race Condition vs. Data Race