Goroutines
fmt sync timeA goroutine is a lightweight thread of execution, managed by the Go runtime. Goroutines are cheap enough to start thousands of them.
package main
import (
"fmt"
"sync"
"time"
)
func f(from string) {
for i := range 3 {
fmt.Println(from, ":", i)
}
}
func main() {Suppose we have a function call f(s). Here's how we'd call that in the usual way, running it synchronously.
f("direct")To invoke this function in a goroutine, use go f(s). This new goroutine will execute concurrently with the calling one.
var wg sync.WaitGroup
wg.Add(1)
go func() {
defer wg.Done()
f("goroutine")
}()You can also start a goroutine for an anonymous function call.
wg.Add(1)
go func(msg string) {
defer wg.Done()
fmt.Println(msg)
}("going")Our two function calls are running asynchronously in separate goroutines now. When main returns, the program exits without waiting for them, so we wait with a WaitGroup (see WaitGroups). A time.Sleep would be a fragile way to wait.
wg.Wait()
fmt.Println("done")When we run this program, we see the output of the blocking call first, then the output of the two goroutines. Their output may be interleaved, because goroutines run concurrently.
start := time.Now()
for range 10_000 {
wg.Go(func() { time.Sleep(10 * time.Millisecond) })
}
wg.Wait()
fmt.Println("10,000 sleeping goroutines took well under a second:", time.Since(start) < time.Second)
}$ go run ./32_goroutines direct : 0 direct : 1 direct : 2 going goroutine : 0 goroutine : 1 goroutine : 2 done 10,000 sleeping goroutines took well under a second: true