获取内存地址的锁,而不是golang中的变量

时间:2019-04-21 18:23:45

标签: go locking mutex heap-memory goroutine

我有一个名为Setter的界面。名为SetterImpl的结构实现了此接口,并具有2个setter,所有这些setter都设置2个接口。

type Setter interface {
    A() *AInterface
    B() *BInterface
}
type SetterImpl struct {
    a *AInterface
    b *BInterface
}

func (s *SetterImpl) A(a *AInterface) {
    a = a
}

func (s *SetterImpl) B(b *AInterface) {
    b = b
}

func returnSetter(a *AInterface, b *BInterface) Setter {
    return &SetterImpl{a:a, b:b}
}

以上方法返回的设置器位于堆中(例如SHeap),并发送到gRPC服务器。现在,我想更新SetterImpl中的a和b,以便gRPC服务器使用新值。

所以我现在有2个goroutine。一个是gRPC服务器主goroutine(例如MAIN),另一个是派生的goroutine(例如FORKED),它只是更新setter字段。

如果我在FORKED中使用Mutex,那实际上是添加了一个围栏(如java)。它实际上并不锁定任何变量(自身除外)。 我不希望MAIN在FORKED更新它们时能够读取存储在SHeap中的a和b。在读取SHeap中的值之前,服务器中的API线程(goroutines)不获取Read Mutex。因此,甚至有可能做我想达到的目标吗?如果是,我该如何实现?

2 个答案:

答案 0 :(得分:1)

我认为您不能在Go中锁定变量。您只能锁定代码段。

m.Lock()
// do stuff
m.Unlock()

通过使用“接口”与“ Impl”模式,您正在为自己创建一个问题。

通过使用常规功能,您可以使生活更简单。然后,您可以将锁放入函数中,并确保将其保护。

由于要创建接口,所以不能保证实现该接口的函数的内容。

答案 1 :(得分:0)

无法锁定变量。所以我想做的是不可能的。 我所做的解决方法是将RWMutex添加到SetterImpl中并进行

mux.RLock()
defer mux.RUnlock()
在SetterImpl中a和b的吸气剂中的

。当我想在FORKED中设置a和b时,我使用了

mux.Lock()
defer mux.Unlock()

这样,如果FORKED获取了写锁,则此时无法获取读锁。这是有可能的,因为在SHeap中创建的RWLock字段用作全局变量(即,该互斥量永远不会更改并沿FORKED传递)