1.sync.Mutex的初始化注意事项
type MemProvider struct {
lock *sync.Mutex //用来锁
sessions map[string]*SessionStore //用来存储在内存
}
初始化时
var lockm *sync.Mutex = new(sync.Mutex)
var memProvider = &MemProvider{sessions: make(map[string](*SessionStore)), lock: lockm}
2.sync.Mutex的嵌套调用注意事项
func (per *MemProvider) SessionInit(sid string) (Session, error) {
per.lock.Lock()
defer per.lock.Unlock()
v := make(map[interface{}]interface{})
fmt.Println("provider init session")
newSess := &SessionStore{sid: sid, timeAccessed: time.Now(), values: v}
per.sessions[sid] = newSess
fmt.Println("provider init finish")
return newSess, nil
}
func (per *MemProvider) SessionRead(sid string) (Session, error) {
per.lock.Lock()
defer per.lock.Unlock()
if sess, ok := per.sessions[sid]; ok {
return sess, nil
} else {
sess, err := per.SessionInit(sid)
return sess, err
}
return nil, nil
}
在SessionRead(sid string)函数中,
当出现per.sessions[sid]中不存在sess时,此时会执行sess.err:= per.SessionInit(sid)函数
在SessionInit(sid string)函数中,首行就出现
per.lock.Lock()
defer per.lock.Unlock()
这就需要per.lock此时属于被释放状态,而在SessionRead(sid string)中调用per.SessionInit(sid)时,此时上一步执行的lock仍然处于lock状态
改进后的代码如下
func (per *MemProvider) SessionInit(sid string) (Session, error) {
per.lock.Lock()
defer per.lock.Unlock()
v := make(map[interface{}]interface{})
newSess := &SessionStore{sid: sid, timeAccessed: time.Now(), values: v}
per.sessions[sid] = newSess
return newSess, nil
}
func (per *MemProvider) SessionRead(sid string) (Session, error) {
per.lock.Lock()
if sess, ok := per.sessions[sid]; ok {
per.lock.Unlock()
return sess, nil
} else {
per.lock.Unlock()
sess, err := per.SessionInit(sid)
return sess, err
}
per.lock.Unlock()
return nil, nil
}
此时,锁问题解决。