dictionary - 使用 sync.Map 确保只有一个 goroutine 正在运行

标签 dictionary go concurrency synchronization locking

我有一个 HTTP 处理程序,它从查询中接收一个参数。我不想为相同的查询参数同时运行此处理程序,即在某个时间点应该只运行一个 goroutine。

这是我的想法:

import "sync"
import "fmt"

var safeMap = sync.Map{}

func handler(c) {

    _, loaded := safeMap.LoadOrStore(c.param, 1) // loaded is true if value was loaded and false if stored 
    fmt.Println(loaded)

    if loaded {
        c.JSON(http.StatusLocked, "locked")
        return
    }

    go doWork(c.param)

    safeMap.Delete(c.param)

    c.JSON(http.StatusOK, "done")
}

但是,每当我发送两个并发请求时,loaded 都为 false,并且两个请求都已处理。为什么?

最佳答案

问题是你在一个新的 goroutine 中做你的工作 (doWork())。如果 param 尚未锁定,则处理程序将其锁定,并启动一个 goroutine 来完成工作。但是服务于请求的 goroutine 不会等待工作完成,它会立即解锁参数。

而是在处理程序中执行工作,因此解锁参数只会在 doWork() 返回时发生:

doWork(c.param) // Note no 'go' keyword

关于dictionary - 使用 sync.Map 确保只有一个 goroutine 正在运行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48862457/

相关文章:

java - 如何按日期对以 TreeMap 作为值的 ArrayList 进行排序

ruby-on-rails - 在 Rails 中根据英语词典验证单词?

mongodb - 使用 Gobson/Mgo 解码 BSON 数据

go - 在 go 中装饰基本数据类型

multithreading - 有没有一种可靠的方法来确保 Go channel 不会在读取时阻塞?

c# - 字典中不存在自定义键类 <string, bool>

javascript从数组创建字典

go - 通过golang将消息以avro格式推送到kafka

java - 如何让进度条 Swing 进度?

scala - 计算 future 列表并返回结果 future