Reputation: 173
I'm trying to get a grasp on goroutines. Take this code:
package main
import "fmt"
var (
b1 []float64
b2 []float64
)
func main() {
go fill(&b1, 10)
go fill(&b2, 10)
fmt.Println(b1,b2)
var s string
fmt.Scanln(&s)
}
func fill(a *[]float64, n int) {
for i:=0; i<n; i++ {
*a = append(*a, rand.Float64()*100)
}
}
As you see, I'm trying to fill two slices. But when run this way (with go fill()
), it prints two empty slices. Why is this not working?
Upvotes: 1
Views: 121
Reputation: 30027
Any goroutines you start aren't guaranteed to have finished (or even started!) until you've explicitly waited on them using a sync.WaitGroup
, channel, or other mechanism. This works:
package main
import (
"fmt"
"math/rand"
"sync"
)
var (
b1 []float64
b2 []float64
)
func main() {
wg := new(sync.WaitGroup)
wg.Add(2)
go fill(&b1, 10, wg)
go fill(&b2, 10, wg)
wg.Wait()
fmt.Println(b1)
fmt.Println(b2)
}
func fill(a *[]float64, n int, wg *sync.WaitGroup) {
for i := 0; i < n; i++ {
*a = append(*a, rand.Float64()*100)
}
wg.Done()
}
(Just speaking of style, if it were me I'd make this function return the enlarged slice so it's similar to append()
itself, and Go's Code Review Comments suggest passing values, though it's not at all unconventional to extend a slice passed as a pointer receiver ("this") parameter.)
Upvotes: 6