client-go和golang源码中的技巧( 二 )
package mainimport ("fmt""sync")var speakCh = make(chan string)var stopReadChan = make(chan struct{})var stopWriteChan = make(chan struct{})func readChan(stopCh <-chan struct{}){for {select {case words := <- speakCh:fmt.Println("received:",words)case <- stopCh:fmt.Println("stop read!")return}}}func writeChan(stopCh <-chan struct{}){for {select {case <- stopCh:fmt.Println("stop write!")close(stopReadChan)returndefault:}speakCh <- "hi"time.Sleep(time.Second*2)}}func main(){go readChan(stopReadChan)go writeChan(stopWriteChan)time.Sleep(time.Second*6)close(stopWriteChan)time.Sleep(time.Second*6)}结果:received: hireceived: hireceived: histop write!stop read!
- 协程间使用context进行同步
官方推荐的用法如下:
func Stream(ctx context.Context, out chan<- Value) error {for {v, err := DoSomething(ctx)if err != nil {return err}select {case <-ctx.Done():return ctx.Err()case out <- v:}}}下例中使用context.WithCancel创建一个context , 使用cancel()给这一组context发送信号 , 在协程中使用Done()处理退出事件 。package mainimport ("fmt""context")func main(){ctx,cancel := context.WithCancel(context.Background())go testCtx(ctx,"ctx1")go testCtx(ctx,"ctx2")go testCtx(ctx,"ctx3")time.Sleep(time.Second*3)cancel()time.Sleep(time.Second*5)}func testCtx(ctx context.Context, name string) error{for {select {case <-ctx.Done():fmt.Println("ctx.Done:",name)return ctx.err()default:fmt.Println("default:",name)time.Sleep(time.Second*2)}}}结果:default: ctx1default: ctx3default: ctx2default: ctx3default: ctx1default: ctx2ctx.Done: ctx1ctx.Done: ctx3ctx.Done: ctx2创建context的方式如下 , 其余三个可以看作是WithCancel的扩展func WithCancel(parent Context) (ctx Context, cancel CancelFunc)//需要主动取消contextfunc WithDeadline(parent Context, deadline time.Time) (Context, CancelFunc)//在deadline时间点后取消contextfunc WithTimeout(parent Context, timeout time.Duration) (Context, CancelFunc) //在超时后取消contextfunc WithValue(parent Context, key, val interface{}) Context再看一个WithTimeout的例子 , 下面设置context的超时时间为3s且没有主动cancel() , 3s超时后可以看到该context对应的协程正常退出func main(){ctx,_ := context.WithTimeout(context.Background(),time.Second*3)go testCtx(ctx,"ctx1")go testCtx(ctx,"ctx2")go testCtx(ctx,"ctx3")time.Sleep(time.Second*5)}结果:default: ctx3default: ctx1default: ctx2default: ctx3default: ctx1default: ctx2ctx.Done: ctx3ctx.Done: ctx2ctx.Done: ctx1context可以看作是一个树 , 当cancel一个context时 , 会同时cancle它的子context 。 下面首先创建一个ctx , 然后在此ctx下面创建一个subctx 。 当执行cancle() ctx时会同时cancel() 该的subctx 。context.Background()就是已经实现的首个context 。
func main(){ctx,cancel := context.WithCancel(context.Background())subctx,_ := context.WithCancel(ctx)go testCtx(ctx,"ctx1")go testCtx(subctx,"subctx1")go testCtx(subctx,"subctx2")time.Sleep(time.Second*3)canclel()time.Sleep(time.Second*10)}结果:default: subctx2default: ctx1default: subctx1default: subctx2default: ctx1default: subctx1timeoutctx.Done: ctx1ctx.Done: subctx1ctx.Done: subctx2下例中仅cancel() subctx , 可以看到并没有影响subctx的parent 。func main(){ctx, _:= context.WithCancel(context.Background())subctx,subcancel := context.WithCancel(ctx)go testCtx(ctx,"ctx1")go testCtx(subctx,"subctx1")go testCtx(subctx,"subctx2")time.Sleep(time.Second*3)subcancel()time.Sleep(time.Second*10)}结果:default: subctx1default: subctx2default: ctx1default: ctx1default: subctx1default: subctx2timeoutctx.Done: subctx2default: ctx1ctx.Done: subctx1default: ctx1default: ctx1default: ctx1default: ctx1- wait.Group(k8s.io/apimachinery/pkg/util/wait/wait.go)
func (g *Group) Wait() func (g *Group) StartWithChannel(stopCh <-chan struct{}, f func(stopCh <-chan struct{}))func (g *Group) StartWithContext(ctx context.Context, f func(context.Context))func main(){f1:= func(ctx context.Context) {for {select {case <- ctx.Done():returndefault:fmt.Println("hi11")time.Sleep(time.Second)}}}wg := wait.Group{}ctx, cancel := context.WithCancel(context.Background())wg.StartWithContext(ctx,f1)time.Sleep(time.Second*3)cancel()wg.Wait()}结果:hihihi
- 中国|浅谈5G移动通信技术的前世和今生
- 芯片|华米GTS2mini和红米手表哪个好 参数功能配置对比
- 桌面|日常使用的软件及网站分享 篇一:几个动态壁纸软件和静态壁纸网站:助你美化你的桌面
- 二维码|村网通?澳大利亚一州推出疫情追踪二维码 还考虑采用人脸识别和地理定位
- 不到|苹果赚了多少?iPhone12成本不到2500元,华为和小米的利润呢?
- 机器人|网络里面的假消息忽悠了非常多的小喷子和小机器人
- 华为|骁龙870和骁龙855区别都是7nm芯片吗 性能对比评测
- 花15.5亿元与中粮包装握手言和 加多宝离上市又进一步?|15楼财经 | 清远加多宝
- 和谐|人民日报海外版今日聚焦云南西双版纳 看科技如何助力人象和谐
- 内容|浅谈内容行业的一些规律和壁垒,聊聊电商平台孵化小红书难点(外部原因)
