Go 协程 是与其他函数或方法一起并发运行的函数或方法。Go 协程可以看作是轻量级线程。与线程相比,创建一个 Go 协程的成本很小。因此在 Go 应用中,常常会看到有数以千计的 Go 协程并发地运行。
启动一个 go 协程
调用函数或者方法时,如果在前面加上关键字 go
,就可以让一个新的 Go 协程并发地运行。
// 定义一个函数
func function_name() {
code
}
// 执行一个函数
function_name()
// 开启一个协程执行这个函数
go function_name()
下面是启动一个协程的例子, go PrintfA()
语句启动了一个新的协程, PrintfA()
函数与 main()
函数会并发执行,主函数运行在一个特殊的协程上,这个协程称之为 主协程(Main Goroutine) 。
启动一个新的协程时,协程的调用会立即返回。与函数不同,程序控制不会去等待 Go 协程执行完毕。在调用 Go 协程之后,程序控制会立即返回到代码的下一行,忽略该协程的任何返回值。如果 Go 主协程终止,则程序终止,于是其他 Go 协程也不会继续运行。为了让新的协程能继续运行,我们在 main()
函数添加了 time.Sleep(1 * time.Second)
使主协程休眠 1 秒,但这种做法并不推荐,这里只是为了演示而添加。
package main
import (
"fmt"
"time"
)
func PrintfA() {
fmt.Println("A")
}
func main() {
// 开启一个协程执行 PrintfA 函数
go PrintfA()
// 使主协程休眠 1 秒
time.Sleep(1 * time.Second)
// 打印 main
fmt.Println("main")
}
运行上面的程序输出如下:
A
main
启动多个 go 协程
通过下面的例子,可以观察到两个协程就如两个线程一样,并发执行:
package main
import (
"fmt"
"time"
)
func Print(num int) {
for i := 0; i < 5; i++ {
fmt.Println(num)
// 避免观察不到并发效果 加个休眠
time.Sleep(time.Millisecond)
}
}
func main() {
// 开启 1 号协程
go Print(1)
// 开启 2 号协程
go Print(2)
// 使主协程休眠 1 秒
time.Sleep(time.Second)
}
运行该程序的一种输出如下:
2
1
1
2
2
1
1
2
2
1
参考文献:
[1] Alan A. A. Donovan; Brian W. Kernighan, Go 程序设计语言, Translated by 李道兵, 高博, 庞向才, 金鑫鑫 and 林齐斌, 机械工业出版社, 2017.