- The program goroutine3.go illustrates how we can use different WaitGroups for groups of functions.
- We use numEvenFuncs for the even-numbered goroutines and numOddFuncs for the odd-numbered goroutines.
/* goroutine3.go concurrent functions with even-odd sync */ package main import ("fmt"; "sync"; "math/rand"; "os"; "strconv") func myFunction(id int, numEvenFuncs, numOddFuncs *sync.WaitGroup) { fmt.Printf("\nmyFunction %2d:",id) var sum float64 for i := 0; i < 10000; i++ { sum+=rand.Float64() } switch id%2{ case 0: numEvenFuncs.Done() case 1: numOddFuncs.Done() } fmt.Printf("\ndone %7.3e id %2d",sum,id) } func main() { if len(os.Args) < 2 { fmt.Printf("usage <filename> seed\n") return } seed, _ := strconv.Atoi(os.Args[1]) rand.Seed(int64(seed)) var numEvenFuncs, numOddFuncs sync.WaitGroup fmt.Printf("\n--start main program--") numEvenFuncs.Add(10) numOddFuncs.Add(10) for i := 0; i < 20; i++ { go myFunction(i, &numEvenFuncs, &numOddFuncs) } numEvenFuncs.Wait() fmt.Printf("\n--end EVEN goroutines--\n") numOddFuncs.Wait() fmt.Printf("\n--end ODD goroutines--\n") fmt.Printf("\n--end main program--\n") }
It is instructive to run this program repeatedly and examine the output.
Here is an interesting example:
$ go run goroutine3.go 81 --start main program-- myFunction 19: done 5.030e+03 id 19 myFunction 0: done 4.982e+03 id 0 myFunction 1: done 5.027e+03 id 1 myFunction 2: done 4.967e+03 id 2 myFunction 3: done 5.013e+03 id 3 myFunction 4: done 4.999e+03 id 4 myFunction 5: done 4.944e+03 id 5 myFunction 12: myFunction 9: myFunction 10: done 4.999e+03 id 10 myFunction 11: myFunction 7: myFunction 6: myFunction 15: myFunction 17: myFunction 13: myFunction 16: myFunction 14: myFunction 18: myFunction 8: done 5.018e+03 id 9 done 5.027e+03 id 16 done 5.000e+03 id 17 done 4.985e+03 id 14 done 5.006e+03 id 12 done 5.027e+03 id 11 done 5.058e+03 id 6 done 5.014e+03 id 7 done 5.034e+03 id 15 done 4.965e+03 id 18 done 5.049e+03 id 8 --end EVEN goroutines-- done 5.039e+03 id 13 --end ODD goroutines-- --end main program--
- We notice that 10 each of even and odd functions are launched.
- They are not launched in a sequential order. This is a property of concurrent and parallel programs.
- 10 each of even and odd functions are concluded. They do not conclude in the order in which they were launched (again caused by concurrent or parallel execution).
- One odd goroutine is still active after all the even goroutines have finished.
- The program runs correctly: 10 each of the even and odd routines are launched and conclude, before the main program concludes.
- You can experiment with this further by
- Changing the seed.
- Changing the number of functions.
- Putting a separate load on your machine (e.g. by running a separate resource-consuming program in a separate window).