在包级别声明互斥变量是一种好习惯吗?
Declare mutex variable in package level is good practice?
在一个包中,我声明了一些变量和一个互斥变量。
我想用它来锁定或解锁 get/set 个包级变量。
var mutex sync.Mutex
var tplPath = ""
func Prepare(c *gin.Context) {
mutex.Lock()
tplPath = "abc"
mutex.Unlock()
}
在并发 http 请求中使用 mutex 可以防止 tplPath 上 get/set 的竞争条件,这是否可以被视为良好实践?
使用包级变量并不总是好的或总是坏的。视问题而定。
关于此特定代码示例的唯一问题是,您可能最终会处于在代码中的多个位置锁定和解锁的状态。
如果您选择走这条路;这很好,考虑将 tplPath
和 mutex
提取到一个类型中。
// create type and expose values through getters and setters
// to ensure the mutex logic is encapsulated.
type path struct {
mu sync.Mutex
val string
}
func (p *path) setPath(path string) {
p.mu.Lock()
defer p.mu.Unlock()
p.val = path
}
func (p *path) path() string {
p.mu.Lock()
defer p.mu.Unlock()
return p.val
}
var tplPath *path
func init() {
// use package init to make sure path is always instantiated
tplPath = new(path)
}
func Prepare(c *gin.Context) {
tplPath.setPath("abc")
}
在一个包中,我声明了一些变量和一个互斥变量。 我想用它来锁定或解锁 get/set 个包级变量。
var mutex sync.Mutex
var tplPath = ""
func Prepare(c *gin.Context) {
mutex.Lock()
tplPath = "abc"
mutex.Unlock()
}
在并发 http 请求中使用 mutex 可以防止 tplPath 上 get/set 的竞争条件,这是否可以被视为良好实践?
使用包级变量并不总是好的或总是坏的。视问题而定。
关于此特定代码示例的唯一问题是,您可能最终会处于在代码中的多个位置锁定和解锁的状态。
如果您选择走这条路;这很好,考虑将 tplPath
和 mutex
提取到一个类型中。
// create type and expose values through getters and setters
// to ensure the mutex logic is encapsulated.
type path struct {
mu sync.Mutex
val string
}
func (p *path) setPath(path string) {
p.mu.Lock()
defer p.mu.Unlock()
p.val = path
}
func (p *path) path() string {
p.mu.Lock()
defer p.mu.Unlock()
return p.val
}
var tplPath *path
func init() {
// use package init to make sure path is always instantiated
tplPath = new(path)
}
func Prepare(c *gin.Context) {
tplPath.setPath("abc")
}