如何在Golang中对多个变量应用单独的互斥锁?

huangapple go评论81阅读模式
英文:

How to apply separate Mutex on multiple variables in Golang?

问题

我有多个变量,我想使用这种方法使它们相互排斥<br>

type var1WithMutex struct {
    mu       sync.Mutex
    var1     int
}
func (v *var1) Set(value int) {
    v.mu.Lock()
    v.var1 = value
    v.mu.Unlock()
}
func (v *var1) Get() (value int) {
    v.mu.Lock()
    value = v.var1
    v.mu.Unlock()
    return
}

类似地,还有数百个变量,如var1、var2、var3... var100<br>
如何在不重复这段代码的情况下使它们全部相互排斥?<br>
请注意,var1、var2、var3等不是数组的一部分,它们之间也没有任何关联。var2可能是一个int,而var3可能是一个User{}。

英文:

I have multiple variables which I want to make mutually exclusive using this method <br>

type var1WithMutex struct {
    mu       sync.Mutex
    var1     int
}
func (v *var1) Set(value int) {
    v.mu.Lock()
    v.var1 = value
    v.mu.Unlock()
}
func (v *var1) Get() (value int) {
    v.mu.Lock()
    value = v.var1
    v.mu.Unlock()
    return
}

Similarly there are hundreds of variable, like var1, var2, var3.... var100<br>
How do i make all of them mutually exclusive without repeating this code?<br>
Note that var1, var2, var3 etc are not part of an array and no way related to each other. var2 may be a int and var3 may be User{}

答案1

得分: 3

你可以为每种类型创建不同的Mutex对象。Playground

type MutexInt struct {
    sync.Mutex
    v int
}

func (i *MutexInt) Get() int {
    return i.v
}

func (i *MutexInt) Set(v int) {
    i.v = v
}

func main() {
    i := MutexInt{v: 0}
    i.Lock()
    i.Set(2)
    fmt.Println(i.Get())
    i.Unlock()
}

并且可以像这样使用它:

英文:

You could make different Mutex object for each type instead. Playground

type MutexInt struct {
	sync.Mutex
	v int
}

func (i *MutexInt) Get() int {
	return i.v
}

func (i *MutexInt) Set(v int) {
	i.v = v
}

and use it like this

func main() {
    i := MutexInt{v: 0}
    i.Lock()
    i.Set(2)
    fmt.Println(i.Get())
    i.Unlock()
}

答案2

得分: 2

你可以将变量包装起来并使用共享互斥锁,如果它们都具有相同的接口。以下是示例代码的翻译:

type Var interface {
    Get() int
    Set(n int)
}

func Sync(v Var, m *sync.RWMutex) Var {
    return &syncedVar{
        v: v,
        m: m,
    }
}

type syncedVar struct {
    m *sync.RWMutex
    v Var
}

func (v syncedVar) Get() int {
    v.m.RLock()
    defer v.m.RUnlock()
    return v.v.Get()
}

func (v *syncedVar) Set(n int) {
    v.m.Lock()
    defer v.m.Unlock()
    v.v.Set(n)
}

你可以在这里查看原始代码:http://play.golang.org/p/xri2M-rtEY

英文:

You can wrap your variables and use a shared mutex, if they all have the same interface (http://play.golang.org/p/xri2M-rtEY):

type Var interface {
    Get() int
    Set(n int)
}

func Sync(v Var, m *sync.RWMutex) Var {
	return &amp;syncedVar{
		v: v,
		m: m,
	}
}

type syncedVar struct {
	m *sync.RWMutex
	v Var
}

func (v syncedVar) Get() int {
	v.m.RLock()
	defer v.m.RUnlock()
	return v.v.Get()
}

func (v *syncedVar) Set(n int) {
	v.m.Lock()
	defer v.m.Unlock()
	v.v.Set(n)
}

答案3

得分: 2

如果你的变量是原始数据类型(int、float等),请使用sync.atomic包。原子操作不需要互斥锁。

英文:

If your variables are primitive data types (int, float,..), use the sync.atomic package. Atomic operations do not need mutex.

huangapple
  • 本文由 发表于 2014年11月19日 23:34:06
  • 转载请务必保留本文链接:https://go.coder-hub.com/27020749.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定