我有一个带指针接收器的方法,我想知道在这个方法中使用这个指针接收器是否可以安全地在goroutine中使用?或者我应该将此指针接收器作为参数传递?
例如:
func (m *dummyStruct) doSomething {
/* do a bunch of stuff */
go func() {
m.a = x
m.doSomethingElse()
}()
return y
}
我知道通过将m作为参数传递给goroutine我不会出错,但我想知道它是否非常必要
答案 0 :(得分:5)
如果要修改m
的状态,则需要使用互斥锁和小心锁定模式。
除此之外,在大多数情况下,这将增加跨线程边界的上下文切换。
这就是为什么我们有Go成语:
不要通过共享内存进行通信; 相反,通过沟通来分享记忆。
答案 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共享数据的正确方法,因为它会降低性能。最好的选择是渠道。