我们可以使用channels在多个goroutine之间进行同步(synchronize), 下面直接看例子。
例子 1, 使用chan等待一个goroutine结束。
package main
import "fmt"
import "time"
//在这定义一个函数,以goroutine的方式运行。使用done这个chan来通知
//其它的函数本函数的工作已成。这个例子是通知main函数。
func worker(done chan bool) {
fmt.Print("working...")
for i:=0;i<10;i++ {
time.Sleep(time.Second)
fmt.Print(".")
}
fmt.Println("done")
// 函数结束时,给chan赋值
done <- true
}
func main() {
// Start a worker goroutine, giving it the channel to
// notify on.
//启动一个goroutine并给传入一个chan
c := make(chan bool, 1)
go worker(c)
// main函数在没有收到chan的值时会一直block.
<-c //如果没有这句, mai函数会立即退出而不会等待worker
}
例子2, 函数B在 函数A结束后运行。
package main
import (
"fmt"
"time"
)
//定义函数A,以goroutine的方式运行
func workerA(done chan bool){
fmt.Print("A is running")
for i:=0;i<10;i++{
fmt.Print(".")
time.Sleep(1 * time.Second)
}
fmt.Println("done")
done <- true
}
//定义函数B,以gortoutine的方式运行
func workerB(){
fmt.Print("B is running")
for i:=0;i<10;i++{
fmt.Print(".")
time.Sleep(1 * time.Second)
}
fmt.Println("done")
}
func main(){
c:= make(chan bool, 1)
//启动A,传入chan c
go workerA(c)
//只有A运行结束时,B才能运行
select {
case <-c:
go workerB()
//fmt.Println("B is done !")
}
// wait for workerB exit.
// 为防止main函数在B之前退出,等待一段时间。
time.Sleep(20*time.Second)
}