Redigo是一个用于redis数据库的golang客户端。它使用结构Pool
来维护连接池。此结构包含一个互斥锁,用于应用程序并行放置和获取连接。
type Pool struct {
// ...
IdleTimeout time.Duration
mu sync.Mutex
// Stack of idleConn with most recently used at the front.
idle list.List
}
在其get
方法中,连接池首先删除过时的(空闲超时)连接。当发现一个过时的连接时,池将弹出它,释放锁,然后关闭连接,再次尝试获取锁。
func (p *Pool) get() (Conn, error) {
p.mu.Lock()
// Prune stale connections.
if timeout := p.IdleTimeout; timeout > 0 {
for i, n := 0, p.idle.Len(); i < n; i++ {
e := p.idle.Back()
if e == nil {
break
}
ic := e.Value.(idleConn)
if ic.t.Add(timeout).After(nowFunc()) {
break
}
p.idle.Remove(e)
p.release()
// Why does pool unlock and try to acquire lock again?
p.mu.Unlock()
// Close this stale connection.
ic.c.Close()
p.mu.Lock()
}
}
为什么池会解锁并再次尝试获取锁,而不是在函数返回之前解锁?我想关闭一个连接可能会花费相当多的时间,这会减慢等待这个互斥锁的其他goroutine的速度。
下面是完整的Pool get method
发布于 2017-03-13 10:22:41
关闭一个连接可能会花费相当多的时间,这会减慢等待这个互斥锁的其他goroutine。正如@Cerise Limón所说的那样--现在锁定所有池的使用似乎是不明智的。
在解锁互斥锁之后,其中一个等待的goroutine获得互斥锁。虽然get
方法的goroutine仍然需要删除陈旧的连接,但put
方法的goroutine方法可以将连接放入池中,并尽快继续执行其他工作。
https://stackoverflow.com/questions/42754823
复制相似问题