我有一个正在运行的 go 服务,它在内存中有一个 map ,比如 map1。 map 数据(键和值)依赖于存储在 S3 中的文件。一个 goroutine 正在运行以监控这个文件,如果有变化,下载文件,解析它,并创建一个新的 map ,比如 map2。如何在不导致其他线程读取不一致数据的情况下交换 map1 和 map2 的内容?
下面我大致了解了我是如何考虑解决这个问题的。以下程序的输出是“map1-a”序列,后跟“map2-a”序列。 map 换了。这是最好的方法吗?
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)
}
}
最佳答案
这就是互斥体的目的;将读取和写入包装在 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)
}
}
关于go - 如何在程序运行时安全地交换内存映射?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48571866/