为了账号安全,请及时绑定邮箱和手机立即绑定

【九月打卡】第14天 go语言并发任务的控制

标签:
Go

课程名称GO开发工程师

课程章节:6-8:并发任务非控制

课程讲师ccmouse

课程内容

  1. 非阻塞等待代码示例
func nonBlockingWait(c chan string) (string, bool) {
	select {
	case m := <-c:
		return m, true
	default: // 加了default就实现了非阻塞式等待
		return "", false
	}
}

  1. 等待超时代码示例
func timeOutWait(c chan string, timeout time.Duration) (string, bool) {
	select {
	case m := <-c:
		return m, true
	case <-time.After(timeout):
		return "", false
	}
}
  1. 优雅退出:
// chan bool / chan struct{} 都可以, chan struct{}更省空间
func msgGenDone(name string, done chan struct{}) chan string {
	c := make(chan string)
	go func() {
		i := 0
		for {
			select {
			case <-time.After(time.Duration(rand.Intn(5000)) * time.Second):
				c <- fmt.Sprintf("message: %s--->%d", name, i)
			case <-done: // 收到调用方退出的消息,开始执行清理工作
				fmt.Println("clean start")
				time.Sleep(2 * time.Second)
				fmt.Println("clean done")
				done <- struct{}{} // 清理完成后通知调用方
				return
			}
			i++
		}
	}()
	return c
}

课程收获

  1. 问题: 关于time.After()
    每一次执行select的时, time.After()都会产生一个Time chan去等待。
    就算本次select结束以后,没有超时,这个Time chan 占用的空间会在各自的时间到期前越积越多吧。
    解答:
    Timer只有在时间到达才会被垃圾回收收回。如果需要更好的效率,建议采用NewTimer,然后在不需要的时候调用Timer.Stop

  2. 问题:在一个goruntine发生异常后,通知其它goruntine结束
    解答:
    go语言没有“异常”的说法,只有error和panic。error的话,和我视频里的逻辑一样,通过done channel通知其他goroutine。
    panic的话,可以参考之前的有关defer/panic/recover章节,recover了以后再通过done channel通知。
    当然,我们通知的数据可以考虑包括done的原因,比如说是超时还是出错等。

图片描述
图片描述

点击查看更多内容
1人点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消