我正在编写一个golang API,它接受一个tableName值和一个updEpoch值,即:
curl -F "tableName=abc" -F "updEpoch=123" myhost:8080/singleroute
curl -F "tableName=abc" -F "updEpoch=456" myhost:8080/singleroute
curl -F "tableName=def" -F "updEpoch=123" myhost:8080/singleroute
curl -F "tableName=def" -F "updEpoch=345" myhost:8080/singleroute
我希望允许并行处理多个不同的tableName请求,但每个tableName只能同时处理1个请求。因此,在上面的示例中,如果同时触发以上4个请求,则第1个和第3个应该能够同时运行(作为唯一的表名),但是2ND只会在1 ND完成后启动,4 ND只会在3 ND完成后启动。当我研究互斥锁时,似乎没有任何例子适合这种情况,我不想在代码中的任何地方硬编码abc/def.etc,因为相同的规则应该适用于任何任意的tableName。
根据克罗曼的帮助我猜
package main
import (
"fmt"
"sync"
"time"
"http"
)
km := KeyedMutex{}
type KeyedMutex struct {
mutexes sync.Map // Zero value is empty and ready for use
}
func (m *KeyedMutex) Lock(key string) func() {
value, _ := m.mutexes.LoadOrStore(key, &sync.Mutex{})
mtx := value.(*sync.Mutex)
mtx.Lock()
return func() { mtx.Unlock() }
}
func myFunc(key string, data string) string {
//do some stuff
return "done for key:"+key+", data: "+data
}
func main() {
key := //some form value sent to my api
data := //some form value sent to my api
unlock := km.Lock(key)
defer unlock()
retVal := myFunc(key, data)
}
2条答案
按热度按时间gojuced71#
可以使用
sync.Map
,将表名作为键,将*sync.Mutex
作为值。例如:
示例输出:
以显示具有不同表名的请求立即获得互斥锁,但是具有相同表名的请求被序列化。
wxclj1h52#
您可以创建一个包级别
var map[string]*sync.Mutex
,并锁定将通过表名获取/创建的相应互斥锁。