Golang 中的并发是函数相互独立运行的能力。Goroutines 是并发运行的函数。Golang 提供了 Goroutines 作为并发处理操作的一种方式。
创建一个协程非常简单,就是在一个任务函数前面添加一个go关键字:
go task()
1.没有Goroutines时,程序是由上往下串行,代码实例
package main
import (
"fmt"
"time"
)
func show(msg string) {
for i := 0; i < 5; i++ {
fmt.Printf("msg: %v\n", msg)
time.Sleep(time.Millisecond * 100)
}
}
func main() {
show("php")
show("golang")
fmt.Println("end...")
}
运行结果
msg: php
msg: php
msg: php
msg: php
msg: php
msg: golang
msg: golang
msg: golang
msg: golang
msg: golang
end...
2.当使用Goroutines时,并发执行 (主协程和其他协程并发执行)
package main
import (
"fmt"
"time"
)
func show(msg string) {
for i := 0; i < 5; i++ {
fmt.Printf("msg: %v\n", msg)
time.Sleep(time.Millisecond * 100)
}
}
func main() {
go show("php") //协程1
show("golang")
fmt.Println("end...") //都有的主协程,主协程和协程1并发执行
}
运行结果
msg: golang
msg: php
msg: php
msg: golang
msg: golang
msg: php
msg: php
msg: golang
msg: php
msg: golang
end...
3.当主协程结束后,其他协程也会终止
package main
import (
"fmt"
"time"
)
func show(msg string) {
for i := 0; i < 5; i++ {
fmt.Printf("msg: %v\n", msg)
time.Sleep(time.Millisecond * 100)
}
}
func main() {
go show("php") //协程1
go show("golang") //协程2
fmt.Println("end...") //主协程执行的时间短,结束后协程1和协程2也终止
}
运行结果
end...
msg: golang
4.WaitGroup实现同步(主协程等待其他协程完成后再往下执行)
package main
import (
"fmt"
"sync"
"time"
)
var wg sync.WaitGroup
func show(msg string) {
defer wg.Done() //goroutine结束就登记-1 也可用 wg.Add(-1)
for i := 0; i < 5; i++ {
fmt.Printf("msg: %v\n", msg)
time.Sleep(time.Millisecond * 100)
}
}
func main() {
wg.Add(1) //启动一个goroutine就登记+1
go show("php") //协程1
wg.Add(1)
go show("golang") //协程2
wg.Wait() //等待所有登记的goroutine都结束
fmt.Println("end...") //结束后,主协程继续执行
}
运行结果
msg: php
msg: golang
msg: golang
msg: php
msg: php
msg: golang
msg: golang
msg: php
msg: php
msg: golang
end...