并发访问指针方法 [英] Go concurrent access to pointers methods

查看:72
本文介绍了并发访问指针方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图了解当您同时访问指针方法时会发生什么?

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

is the same as

func foo(r *R, bar baz) // A plain old function

换句话说,接收器(无论是否为指针)只是一个参数槽.您的问题现在简化为:

In other words, the receiver, pointer or not, is just an argument slot. Your question now reduces to:

当两个go例程以相同的r值调用上述函数时会发生什么?

What happens when two go routines call the above function with the same value of r?

A:要视情况而定.问题配置:

A: It depends. Problem configurations:

  • foo 出于任何原因均不能重新进入.
  • foo 使 * r (指定对象)变异而没有协调/同步.
  • 最后一点只是以下情况的特例:如果 foo 突变任何共享状态而没有协调/同步:任何事情都可能发生
  • 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值)也是安全的.

If foo avoids the above tar pits then it is safe for being executed concurrently by multiple goroutines even with the same value of r.

这篇关于并发访问指针方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆