【问题标题】:Reliable thread-safe map可靠的线程安全映射
【发布时间】:2020-08-26 14:57:09
【问题描述】:

我正在为我的 Discord 机器人创建一个 WaitForResponse 函数,它可以工作,但即使机器人期待响应,用户仍然可以使用命令。我通过使用带有用户和频道 ID 的地图来解决这个问题,但随后我被可怕的fatal error: concurrent map read and write 击中。所以我尝试使用sync.Map,但是当我发送垃圾邮件命令时它并不总是有效。当机器人期待响应时,我有时仍然可以运行命令。有什么方法可以确保在地图中按应有的方式添加和删除这些值?

【问题讨论】:

    标签: dictionary go concurrency discord


    【解决方案1】:

    对于这些场景,sync.Mutex 可用于确保只允许进行一次修改,方法是在您希望线程安全的代码周围获取

    var mu sync.Mutex
    
    func readMap(key string) {
        mu.Lock()
        defer mu.Unlock()
    
        return yourMap[key]
    }
    
    func updateMap(key, value string) {
        mu.Lock()
        defer mu.Unlock()
    
        yourMap[key] = value
    }
    

    Mutex 确保 ONLY ONE goroutine 可以被允许访问 locked 代码,这意味着对于您的情况,只能执行一个操作,读取或写入。

    为了提高效率,您应该考虑使用sync.RWMutex,因为您可能不想在读取地图时锁定它。来自 GoDoc:

    RWMutex 是读写器互斥锁。锁可以由任意数量的读取器或单个写入器持有。 RWMutex 的零值是未锁定的互斥锁。

    var mu sync.RWMutex
    
    func readMap(key string) {
        mu.RLock()
        defer mu.RUnlock()
    
        return yourMap[key]
    }
    
    func updateMap(key, value string) {
        mu.Lock()
        defer mu.Unlock()
    
        yourMap[key] = value
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-07-08
      • 2011-03-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多