1. Context包方式
package main
import (
"context"
"fmt"
"sync"
"time"
)
var wg =new(sync.WaitGroup) //创建一个等待组
func main(){
ctx,cancel := context.WithCancel(context.Background())
wg.Add(1) //等待组计数+1
go work1(ctx) //跑一个work1 goroutine
exit_with_second(5,cancel) //设置sleep 5秒执行cancel()
wg.Wait() //等待组计数为0 释放阻塞
}
func work1(ctx context.Context){
LOOP:
for{
time.Sleep(time.Second*1)
select {
case x := <-ctx.Done():
fmt.Println("work1 rev :",x)
break LOOP
default:
fmt.Println("work1...")
}
}
fmt.Println("work1 done ...")
wg.Done() //等待组计数-1
}
func exit_with_second(s int,f context.CancelFunc){
time.Sleep(time.Second * time.Duration(s))
f() //执行
}
2. Channel方式
package main
import (
"fmt"
"sync"
"time"
)
var wg = new(sync.WaitGroup)
func main(){
var ch = make(chan int) //创建一个管道
defer close(ch) //程序退出前关闭管道
wg.Add(1)
go work1(ch) //执行一个work1 goroutine
sendnumber(5,ch)
wg.Wait()
}
func work1(c chan int){
LOOP:
for {
time.Sleep(time.Second * 1)
select {
case n := <-c :
fmt.Println("work1 rev:",n)
break LOOP // 从管道接收到数字1 退出循环
default:
fmt.Println("work1 ...")
}
}
fmt.Println("work1 done")
wg.Done()
}
func sendnumber(n int,c chan int){
time.Sleep(time.Second * time.Duration(n))
c <- 1 // 往管道发送数字1
}