在 goroutine 中使用指针接收器

Using a pointer receiver in a goroutine

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

例如:

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

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

如果要修改 m 的状态,则需要互斥锁和谨慎的锁定模式。

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

这就是我们拥有 Go 习语的原因:

Do not communicate by sharing memory; instead, share memory by communicating.

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

我看过 link @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!

我认为指针不是共享 goroutines 数据的正确方式,因为它会降低性能。最好的选择是频道。