问题描述
我试图了解当您同时访问指针方法时会发生什么?
I'm trying to understand what happens when you make concurrent access to a pointers methods?
我有一个指针映射,并生成了一些go例程.我将地图传递到每个go例程中,每个go例程将使用地图中的值之一.只能从中读取任何内容都不会写入地图.
I have a map of pointers and spawn off a few go routines. I pass the map into each go routine and each go routine will use one of the values in the map. Nothing is being written to the map only being read from.
该地图很小,只有4个键,因此有可能多个go例程将使用该地图中的相同值.
The map is small, only 4 keys so it's possible that more than one go routine will be using the same value from the map.
问题是,当两个go例程调用具有相同指针的方法时会发生什么?我会得到意想不到的结果吗?
Question is, what happens when two go routines call a method of the same pointer? Will I get unpredictable results?
编辑
示例:我要取出地图部分,因为这不是我要关注的问题.
Example: I'm taking out the map portion as that's not the question I'm after.
我有 foo
,它是类型为 MyStruct
的指针,并且此结构具有接受参数的方法 DoSomething
.在 main
函数中,我创建了两个 go例程
,它们都通过不同的值调用 foo.DoSomething
.在此示例中,第一次执行例程要进行的计算要比第二次执行例程大得多(仅在此处使用睡眠时间来模拟计算).同样,结构中的任何内容都没有改变,我只调用了structure方法.当第一个go例程仍在使用该方法时,我是否需要担心第二个go例程对 foo.DoSomething
的调用?
I have foo
which is a pointer of type MyStruct
and this structure has a method DoSomething
that takes arguments. In the main
function I'm creating two go routines
and both of them make calls to foo.DoSomething
passing different values. In this example the first go routine has a much larger calculation to preform than the second one (just using sleep times here to simulate calculations). Again nothing in the structure is changing I'm only making a call to the structures method. Do I have to worry about the second go routine making a call to foo.DoSomething
when the first go routine is still working with the method?
package main
import (
"log"
"time"
)
type MyStruct struct {
}
func (self *MyStruct) DoSomething(value int) {
log.Printf("%d Start", value)
calculation_time := time.Duration(value) * time.Second
log.Printf("%d Calculating", value, calculation_time)
time.Sleep(calculation_time)
log.Printf("%d Done", value)
}
func main() {
var foo = new(MyStruct)
go foo.DoSomething(5)
// is this method call a problem when the first one is still working?
go foo.DoSomething(2)
time.Sleep(time.Duration(6 * time.Second))
}
推荐答案
Go方法具有接收者.接收器可以是指针类型.带有签名的方法,例如:
Go methods have receivers. Receiver can be a pointer type. A method with the signature, for example:
func (r *R) foo(bar baz) // A method
是与
func foo(r *R, bar baz) // A plain old function
换句话说,接收器(无论是否为指针)只是一个参数槽.您的问题现在简化为:
A: It depends. Problem configurations:
foo
is not re-entrant for any reason.foo
mutates*r
(the pointee) w/o coordination/synchronization.- The last point is only a special case of: If
foo
mutates any shared state w/o coordination/synchronization: anything can happen.
如果 foo
避免了上述tar坑,那么对于由多个goroutine并发执行(即使具有相同的r值)也是安全的.
这篇关于并发访问指针方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!