协程(Goroutine)是与其他函数或方法同时运行的函数或方法。可以认为它是轻量级的线程。与线程相比,创建 Goroutine 的成本很小。因此,Go 应用程序可以有上千个 Goroutines 同时运行。
在函数或方法调用之前加上关键字 go
,这样便开启了一个并发的 Goroutine。
package main
import (
"fmt"
)
func hello() {
fmt.Println("Hello world goroutine")
}
func main() {
go hello()
fmt.Println("main function")
}
go hello()
开启了一个新的协程。现在 hello()
函数将和 main()
函数一起运行。main()
函数在单独的协程中运行,这个协程称为主协程。
运行上面的程序将仅输出一行文本: main function
。
原因:
当创建一个 Go 协程时,创建这个 Go 协程的语句立即返回并向下继续执行。与函数不同,程序流程不会等待 Go 协程结束再继续执行。
在主协程存在时才能运行其他协程,主协程终止则程序终止,其他协程也将终止。
package main
import (
"fmt"
"time"
)
func hello() {
fmt.Println("Hello world goroutine")
}
func main() {
go hello()
time.Sleep(1 * time.Second)
fmt.Println("main function")
}
开启多个协程:
package main
import (
"fmt"
"time"
)
func numbers() {
for i := 1; i <= 5; i++ {
time.Sleep(250 * time.Millisecond)
fmt.Printf("%d ", i)
}
}
func alphabets() {
for i := 'a'; i <= 'e'; i++ {
time.Sleep(400 * time.Millisecond)
fmt.Printf("%c ", i)
}
}
func main() {
go numbers()
go alphabets()
time.Sleep(3000 * time.Millisecond)
fmt.Println("main terminated")
}
下面的图片描述了这个程序是如何工作的: