gpt4 book ai didi

Golang - 按值锁定

转载 作者:行者123 更新时间:2023-12-03 09:26:21 25 4
gpt4 key购买 nike

我正在编写一个接受 tableName 值和 updEpoch 值的 golang api,即:

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 个以上的请求,那么第一个和第三个应该能够同时运行(作为唯一的 tableNames),但是第二个只会在第一个完成后开始,第四个只会在第三个完成后开始。当我研究互斥锁时,似乎没有任何例子适合这种情况,我不想在代码中的任何地方对 abc/def.etc 进行硬编码,因为相同的规则应该适用于任何任意 tableName。
我的猜测基于 Crowman 的帮助:
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)
}

最佳答案

您可以使用 sync.Map 将您的表名作为键,使用 *sync.Mutex 作为值。
例如:

package main

import (
"fmt"
"sync"
"time"
)

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 main() {
wg := sync.WaitGroup{}
km := KeyedMutex{}

for _, job := range []struct {
key string
data string
}{
{key: "abc", data: "123"},
{key: "abc", data: "456"},
{key: "def", data: "123"},
{key: "def", data: "456"},
} {
var job = job
wg.Add(1)

go func() {
defer wg.Done()

unlock := km.Lock(job.key)
defer unlock()

fmt.Printf("%s:%s mutex acquired\n", job.key, job.data)
time.Sleep(time.Second * 1) // To ensure some goroutines visibly block
fmt.Printf("%s:%s done\n", job.key, job.data)
}()
}

wg.Wait()
}
带有示例输出:
crow@mac:$ ./mut
def:456 mutex acquired
abc:456 mutex acquired
abc:456 done
def:456 done
abc:123 mutex acquired
def:123 mutex acquired
def:123 done
abc:123 done
crow@mac:$
显示具有不同表名的请求立即获得互斥锁,但具有相同表名的请求被序列化。

关于Golang - 按值锁定,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64564781/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com