我使用 Go 映射作为内存缓存和 channel 来确保同步访问。
我的“ session ”包将缓存定义为:map[string]*SessionData
SessionData 是一个也在包中定义的结构,以及代码中看到的其他访问函数。
GetWebPage(rw http.ResponseWriter, req *http.Request) {
var sd *session.SessionData
var sessTkn string
cookie, err := req.Cookie("sesstoken")
if err == nil { // cookie found
sessTkn = cookie.Value
// Check for cache entry for this token,
// using a channel to protect the map and return
// a pointer to the cached data if it exists
sdc := make(chan *session.SessionData, 1)
go session.GetSessionFromCache(sessTkn, sdc)
sd = <-sdc
if sd == nil { // sessTkn not in the cache
// This is test data to simplify example
sv := make([]string, 4)
sv[0] = sessTkn
iv := make([]int, 3)
iv[0] = 100
iv[1] = 1000
sdc := make(chan *session.SessionData, 1)
go session.NewSessionData(sv, iv, false, false, sdc)
session.SC[sessTkn] = <-sdc
}
// Is this necessary? Is there a better way?
// ---------------------------------------
if sd == nil {
sdc = make(chan *session.SessionData, 1)
go session.GetSessionFromCache(sessTkn, sdc)
sd = <-sdc
}
// ---------------------------------------
fmt.Println(sd) // just to prove that it works in both cases
}
// The rest of the handler code follows
最佳答案
使用 mutex来保护 map 。互斥体通常比使用 channel 和协程来保护资源更简单。
var (
mu sync.Mutex
cache = make(map[string]*SessionData)
)
func GetSessionFromCache(sessTkn string) *SessionData {
mu.Lock()
defer mu.Unlock()
sd := cache[sessTkn]
if sd != nil {
return sd
}
sd := &SessionData{
// initialize new value here
}
cache[sessTkn] = sd
return sd
}
像这样使用它:
sd := session.GetSessionFromCache(sessTkn)
关于go - 有没有更好的方法使用 channel 来确保同步访问 map ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44252852/