我有一个go服务运行,在内存中有一个地图,比如map1。地图数据(键和值)依赖于存储在S3中的文件。 goroutine正在运行以监视此文件,如果有更改,则下载文件,解析文件并创建新映射,例如map2。如何在不导致其他线程读取不一致数据的情况下将map1的内容与map2交换?
下面我粗略地了解了我是如何考虑解决这个问题的。以下程序的输出是" map1-a"的序列,后面是" map2-a"的序列。地图被交换了。这是最好的方法吗?
package main
import (
"fmt"
"time"
)
func initializeAndMonitor() *map[string]string {
map1 := make(map[string]string)
map1["a"] = "map1-a"
go func() {
time.Sleep(5 * time.Second)
map2 := make(map[string]string)
map2["a"] = "map2-a"
map1 = map2
}()
return &map1
}
func main() {
map1 := initializeAndMonitor()
for count := 0; count < 100; count = count + 1 {
fmt.Println((*map1)["a"])
time.Sleep(1 * time.Second)
}
}
答案 0 :(得分:2)
这是互斥的目的;将读取和写入包装在sync.RWMutex
:
package main
import (
"fmt"
"time"
"sync"
)
var mu = sync.RWMutex{}
func initializeAndMonitor() *map[string]string {
map1 := make(map[string]string)
map1["a"] = "map1-a"
go func() {
mu.Lock()
defer mu.Unlock()
time.Sleep(5 * time.Second)
map2 := make(map[string]string)
map2["a"] = "map2-a"
map1 = map2
}()
return &map1
}
func main() {
map1 := initializeAndMonitor()
for count := 0; count < 100; count = count + 1 {
mu.RLock()
fmt.Println((*map1)["a"])
mu.RUnlock()
time.Sleep(1 * time.Second)
}
}