golang优雅代码【lock实现】

  • 1.局部锁
    • 1.1 具体实现方式

本文代码风格来源参考 database/sql

1.局部锁

database/sql源码中使用 withLock(dc, func(){...}) 方法实现局部锁,完美利用了 golangdefer 关键字对 入参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 具体实现方式

  1. 首先定义 driverConn 封装 sync.Mutex,实现 sync.Locker 接口
type driverConn struct {
	db        *DB
	...
	sync.Mutex  // guards following
}
  1. 定义函数 withLock ,接收 sync.Locker , func() 入参,在内部实现获取/释放锁,并执行对应函数
// withLock runs while holding lk.
func withLock(lk sync.Locker, fn func()) {
	lk.Lock()
	defer lk.Unlock() // in case fn panics
	fn()
}

  1. 使用该方式实现锁
func (db *DB) queryDC(ctx context.Context, dc *driverConn) (*Rows, error) {
	...
	// 获取&释放锁
	withLock(dc, func() {
		// do something ... 
	})
	...
	return rows, nil
}
  1. 对比普通方式(非常容易忘记释放锁,并且还要考虑errror)
func (db *DB) queryDC(ctx context.Context, dc *driverConn) (*Rows, error) {
	...
	// 获取&释放锁
	dc.Lock()
	// do something ... 
	dc.Unlock()
	...
	return rows, nil
}
本站无任何商业行为
个人在线分享 » golang优雅代码【lock实现】
E-->