天天看点

对于sync.Mutex使用注意事项

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

}

此时,锁问题解决。