This is the second article of a series analyzing Go concurrency, ie, parallel execution of different threads using Go. The series is composed of these articles: The Go concurrency foundation: goroutines . This one, in which synchronization between subprocesses, specifically by using Go waitgroups , is analyzed. Data exchange between subprocesses: Go channels Why synchronization between subprocesses The first article of the series exposed an example that clearly demonstrated why the subprocess synchronization is needed specifically in go: package main import ( "fmt" "time" ) // mySubprocess sleeps for a second func mySubprocess() { fmt.Println("Entering to mySubprocess") time.Sleep(1 * time.Second) fmt.Println("Exiting from mySubprocess") } // main program process func main() { fmt.Println("Calling mySubprocess from main()...") go mySubprocess() fmt.Println("mySubprocess finished!...