Reputation: 10093
At a basic level, I have a main routine that spawns multiple goroutines to process data. Every time a goroutine processes the data it sends back a struct of varying size (it contains slices and/or arrays allocated from within the goroutine each time).
The data isn't huge (say, a few megabytes) but in general is it more efficient (and is it safe) to transfer a pointer to the data versus a copy of it all? If the data structure is static and I transfer a pointer to it, there's a risk that the structure may change while I'm still processing the result of the previous invocation (if it's fully reallocated then perhaps that's not an issue).
Upvotes: 2
Views: 3723
Reputation: 99284
From my understanding you're trying to do something like:
func watchHowISoar() (ch chan *bigData) {
ch = make(chan *bigData)
go func() {
for i := 0; i < 10; i++ {
bd := &bigData{i}
ch <- bd
// as long as you don't modify bd inside this goroutine after sending it, you're safe.
}
close(ch)
}()
return
}
func main() {
for iamaleafOnTheWind := range watchHowISoar() {
fmt.Printf("%p\n", iamaleafOnTheWind)
}
}
And it is perfectly safe as long as you don't modify the sent data from the sender after you send it.
If you have doubts, try to run it with go run -race main.go
, while the race detector isn't perfect, it will usually detect things like that.
Upvotes: 4
Reputation: 6425
It's OK and common to send pointers to values. If the value is large, sending a pointer to the value will be more efficient than sending the value. Run a benchmark to find out how large is "large".
The caveat is that you must prevent unsafe concurrent access to the value. Common strategies for preventing unsafe concurrent access are:
Upvotes: 4