golang优雅代码【lock实现】
- 1.局部锁
- 1.1 具体实现方式
本文代码风格来源参考
database/sql包
1.局部锁
database/sql源码中使用 withLock(dc, func(){...}) 方法实现局部锁,完美利用了 golang 的 defer 关键字对 入参dc 进行加锁解锁,感觉实现很优雅
func (db *DB) queryDC(ctx, txctx context.Context, dc *driverConn, releaseConn func(error), query string, args []any) (*Rows, error) {queryerCtx, ok := dc.ci.(driver.QueryerContext)...if ok {...withLock(dc, func() {// do something ... })...}...return rows, nil
}
1.1 具体实现方式
- 首先定义
driverConn封装sync.Mutex,实现sync.Locker接口
type driverConn struct {db *DB...sync.Mutex // guards following
}
- 定义函数
withLock,接收sync.Locker,func()入参,在内部实现获取/释放锁,并执行对应函数
// withLock runs while holding lk.
func withLock(lk sync.Locker, fn func()) {lk.Lock()defer lk.Unlock() // in case fn panicsfn()
}
- 使用该方式实现锁
func (db *DB) queryDC(ctx context.Context, dc *driverConn) (*Rows, error) {...// 获取&释放锁withLock(dc, func() {// do something ... })...return rows, nil
}
- 对比普通方式(非常容易忘记释放锁,并且还要考虑errror)
func (db *DB) queryDC(ctx context.Context, dc *driverConn) (*Rows, error) {...// 获取&释放锁dc.Lock()// do something ... dc.Unlock()...return rows, nil
}