关于golang的context控制协程的例子
2018-09-13 本文已影响0人
llicety
关于context的概念,可以参考http://www.flysnow.org/2017/05/12/go-in-action-go-context.html
协程间的通信方式
1.共享变量(需要注意资源竞争,一般用互斥锁)
2.chan
3.context
以下是context的代码例子
package main
import (
"sync"
"fmt"
"time"
"context"
"math/rand"
)
func test1(wg * sync.WaitGroup, ctx context.Context, cfunc context.CancelFunc){
defer wg.Done()
fmt.Println("test1 run")
d := time.Duration(rand.Intn(10))
fmt.Printf("%d 秒之后,test1 将终止\n", d)
time.AfterFunc( d * time.Second, cfunc)
for{
select {
case <-ctx.Done():
fmt.Println("test1 return")
return
default:
fmt.Println("default")
time.Sleep(1 * time.Second)
}
}
}
func test2(wg *sync.WaitGroup, ctx context.Context, cfunc context.CancelFunc){
defer wg.Done()
fmt.Println("test2 run")
d := time.Duration(rand.Intn(10))
fmt.Printf("%d 秒之后,test2 将终止\n", d)
time.AfterFunc( d * time.Second, cfunc)
for {
select {
case <-ctx.Done():
fmt.Println("test2 return")
// 这里要不用return 要不就用break + lebal, 不能直接用break,只用break,这里只跳出case
return
default:
fmt.Println("test2 default")
time.Sleep(1 * time.Second)
}
}
}
func main() {
wg := sync.WaitGroup{}
rand.Seed(time.Now().UnixNano())
ctx, cancel := context.WithCancel(context.Background())
wg.Add(2)
timeStart := time.Now().Unix()
go test1(&wg, ctx, cancel)
go test2(&wg, ctx, cancel)
wg.Wait()
timeEnd := time.Now().Unix()
fmt.Printf("运行时长为:%d s\n", timeEnd - timeStart)
fmt.Println("主协成退出!")
}