I have a method with a pointer receiver, I was wondering if using this pointer receiver is safe to use inside a goroutine within this method? or should I pass this pointer receiver as a parameter?
for example:
func (m *dummyStruct) doSomething {
/* do a bunch of stuff */
go func() {
m.a = x
m.doSomethingElse()
}()
return y
}
I know that I can not go wrong by passing m as a parameter to the goroutine but I was wondering if it is extremely necessary
If you are modifying state of m
, you'll need a mutex lock and careful locking patterns.
Other than that, this will increase context switching across your thread boundries under most circumstances.
This is why we have the Go idiom:
Do not communicate by sharing memory; instead, share memory by communicating.
I'd seen the link @eduncan911 posted but never tried to apply it. Hopefully this example helps:
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!
I think Pointer is not the right way to share data with respect to goroutines, as it will decrease the performance. The best option is channels.