在goroutine中使用指针接收器

时间:2016-09-16 18:12:56

标签: go concurrency goroutine

我有一个带指针接收器的方法,我想知道在这个方法中使用这个指针接收器是否可以安全地在goroutine中使用?或者我应该将此指针接收器作为参数传递?

例如:

func (m *dummyStruct) doSomething {
    /* do a bunch of stuff */
    go func() {
        m.a = x
        m.doSomethingElse()
    }()
    return y
}

我知道通过将m作为参数传递给goroutine我不会出错,但我想知道它是否非常必要

3 个答案:

答案 0 :(得分:5)

如果要修改m的状态,则需要使用互斥锁和小心锁定模式。

除此之外,在大多数情况下,这将增加跨线程边界的上下文切换。

这就是为什么我们有Go成语:

  

不要通过共享内存进行通信;   相反,通过沟通来分享记忆。

https://blog.golang.org/share-memory-by-communicating

答案 1 :(得分:0)

我看过链接@ eduncan911已发布,但从未尝试过应用它。希望这个例子有所帮助:

package main

import (
    "fmt"
    "time"
)

type dummyStruct struct {
    a int
}

func (m *dummyStruct) doSomethingElse() {
    fmt.Println(m.a)
}

func doSomething(c chan int) {
    for i := 0; i < 5; i++ {
        go func() {
            x := time.Now().Unix()
            c <- int(x)
        }()
        time.Sleep(time.Second)
    }
}

func main() {
    outputs := make(chan int)
    m := &dummyStruct{}
    doSomething(outputs)
    for {
        //block until we can read from channel:
        x := <-outputs
        m.a = x
        m.doSomethingElse()
    }
}

//Output:
go run main.go
1474052448
1474052449
1474052450
1474052451
1474052452
fatal error: all goroutines are asleep - deadlock!

答案 2 :(得分:0)

我认为Pointer不是与goroutine共享数据的正确方法,因为它会降低性能。最好的选择是渠道。