以下两段代码,我不明白第一个读锁的意义是什么?为什么需要这个锁
```
func (mux *ServeMux) handler(host, path string) (h Handler, pattern string) {
mux.mu.RLock()
defer mux.mu.RUnlock()
// Host-specific pattern takes precedence over generic ones
if mux.hosts {
h, pattern = mux.match(host + path)
}
if h == nil {
h, pattern = mux.match(path)
}
if h == nil {
h, pattern = NotFoundHandler(), ""
}
return
}
```
这里这个锁我能想到的情况是,避免在使用goroutine注册路由时导致数据安全问题
```
func (mux *ServeMux) Handle(pattern string, handler Handler) {
mux.mu.Lock()
defer mux.mu.Unlock()
if pattern == "" {
panic("http: invalid pattern " + pattern)
}
if handler == nil {
panic("http: nil handler")
}
if mux.m[pattern].explicit {
panic("http: multiple registrations for " + pattern)
}
if mux.m == nil {
mux.m = make(map[string]muxEntry)
}
mux.m[pattern] = muxEntry{explicit: true, h: handler, pattern: pattern}
if pattern[0] != '/' {
mux.hosts = true
}
// Helpful behavior:
// If pattern is /tree/, insert an implicit permanent redirect for /tree.
// It can be overridden by an explicit registration.
n := len(pattern)
if n > 0 && pattern[n-1] == '/' && !mux.m[pattern[0:n-1]].explicit {
// If pattern contains a host name, strip it and use remaining
// path for redirect.
path := pattern
if pattern[0] != '/' {
// In pattern, at least the last character is a '/', so
// strings.Index can't be -1.
path = pattern[strings.Index(pattern, "/"):]
}
url := &url.URL{Path: path}
mux.m[pattern[0:n-1]] = muxEntry{h: RedirectHandler(url.String(), StatusMovedPermanently), pattern: pattern}
}
}
```
读写锁的机制是都是读取则不进行锁定,一旦有写写操作获取写锁时,读锁也锁定。这种机制是为了在读多写少的情景下,提高效率。
第一个读锁,大部分情况下都是读操作,是不进行锁定的;当有写锁(第二个锁)时,第一个也是锁定的,保证获取的是最新的数据,也就是写操作更新以后的数据。
#1
更多评论
明白了,谢谢!
之前一直纠结于,根据以往的经验,所有的路由在程序启动阶段应该就注册好了,那么在运行web服务,监听请求的时候,路由应该是保持固定的了,也就是不会再有写操作。
#2