我有一个 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/