省水利工程建设信息网站,ppt制作软件手机版下载免费,2024前端就业形势,html编辑器的功能介绍golang优雅代码【lock实现】 1.局部锁1.1 具体实现方式 本文代码风格来源参考 database/sql 包 1.局部锁
database/sql源码中使用 withLock(dc, func(){...}) 方法实现局部锁#xff0c;完美利用了 golang 的 defer 关键字对 入参dc 进行加锁解锁#xff0c;感觉实现很优雅… 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
}