go - 如何在程序运行时安全地交换内存映射?

标签 go concurrency

我有一个正在运行的 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/

相关文章:

go - `go build` 与 `go build file.go`

java - 涉及 Swing 和 AWT-EventQueue 的无响应线程

java - 在 ConcurrentHashMap 线程安全内同时更新 BigDecimal

java - 我正在开发的一个项目有很多 ConcurrentHashMap 的包装类,并且以(我认为)不正确的方式使用锁。它是否正确?

objective-c - 如果我打算稍后优化并发性,我应该如何在 Cocoa 中设计通知?

mongodb - 为什么在尝试从mongo集合中获取文档时为什么会出现 “client disconnected”错误?

multithreading - Go 如何处理 Google App Engine 上的并发请求

go - 在Golang中执行SSH

go - 将 slice 中的单个字符串替换为一组字符串

java - 如何防止同一类实例中的不同线程同时执行方法