gpt4 book ai didi

caching - Go 中的 RWMutex 未按预期工作

转载 作者:数据小太阳 更新时间:2023-10-29 03:03:10 26 4
gpt4 key购买 nike

我使用 sync.RWMutex 编写了以下示例程序。

package main

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

// SessionData : capture session id and cc-request-number
type SessionData struct {
id string
reqNo string
}

// SessionCache : cache for the SessionData
type SessionCache struct {
sess map[SessionData]bool
sync.RWMutex
}

// InitSessionCache : Init for SessionCache
func InitSessionCache() SessionCache {
return SessionCache{sess: make(map[SessionData]bool)}
}

// Read : read value from session cache
func (s *SessionCache) Read(sd SessionData) bool {
s.RLock()
defer s.RUnlock()

_, found := s.sess[sd]
return found
}

func (s *SessionCache) Write(sd SessionData) {
s.Lock()
defer s.Unlock()
fmt.Println("Entry not found for ", sd.id, sd.reqNo, "Creating the entry now")
s.sess[sd] = true
}

func (s *SessionCache) chkDuplicate(sessionID string, Reqno string) bool {

sd := SessionData{
id: sessionID,
reqNo: Reqno,
}

found := s.Read(sd)
if !found {
s.Write(sd)
return found
}
return found
}

func main() {
mySessionData := InitSessionCache()

for i := 0; i < 10; i++ {
go mySessionData.chkDuplicate("session1", "1")
go mySessionData.chkDuplicate("session1", "1")
go mySessionData.chkDuplicate("session1", "2")
go mySessionData.chkDuplicate("session1", "2")
go mySessionData.chkDuplicate("session1", "4")
go mySessionData.chkDuplicate("session1", "2")
}
time.Sleep(300)
fmt.Println(mySessionData)

}

当我在 Playground 上运行这个程序时 https://play.golang.org/p/g93UtVxZ2dl我看到它工作正常,因为唯一值的写入仅发生 3 次。

Entry not found for  session1 1 Creating the entry now
Entry not found for session1 2 Creating the entry now
Entry not found for session1 4 Creating the entry now
{map[{session1 1}:true {session1 2}:true {session1 4}:true] {{0 0} 0 0 0 0}}

但是,当我从我的 Windows 10 计算机(在 VS Code 上)运行相同的程序时,我看到以下输出。

Entry not found for  session1 1 Creating the entry now
Entry not found for session1 2 Creating the entry now
Entry not found for session1 2 Creating the entry now
Entry not found for session1 2 Creating the entry now
Entry not found for session1 4 Creating the entry now
{map[{session1 1}:true {session1 2}:true {session1 4}:true] {{0 0} 0 0 0 0}}

我做错了什么吗?为什么这在我的机器和 Playground 上表现不同?

最佳答案

调用ReadWrite 之间没有同步。你所有的 goroutines 都在同时运行,想象一下如果它们都运行到这一行然后让给另一个 goroutine:

找到 := s.Read(sd)

它们都将返回 false 因为没有一个 goroutines 移动过这个点。现在他们都转到下一行并相信 found == false,所以都执行 s.Write(sd)

您需要在不解锁的情况下进行读写操作。也许是这样的:

func (s *SessionCache) TryWrite(sd SessionData) err {
s.Lock()
defer s.Unlock()

if _, found := s.sess[sd]; found {
return fmt.Errorf("Entry already exists")
}

s.sess[sd] = true
}

关于caching - Go 中的 RWMutex 未按预期工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50289233/

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