关于select里的空default和没有default的疑问

Vermouth · · 110 次点击 · 开始浏览    置顶
上个简略代码,一个协程往channel写一个读 ``` func add(){ for { now := time.Now() t := modle.EsTask{ Index: fmt.Sprintf("xxxx%v", now.Format("200601")) } EsChan <- t time.Sleep(time.Second * 60) } } func read(){ for { select { case t := <-EsChan: _, err := getPullFromES(t.Index) fmt.Println("start...") if err != nil { fmt.Printf("获取es数据失败:%v", err) } //default: // time.Sleep(time.Second * 10) } } } func main(){ go add() go read() time.Sleep(time.Second * 100) } ``` 现象一:这样read()里没有default会一直阻塞,不会打start... ``` func main(){ go add() time.Sleep(time.Second * 2) go read() time.Sleep(time.Second * 100) } ``` 现象二:这样read()里没有default不会阻塞,会打start... ``` func main(){ go add() for { select { case t := <-EsChan: _, err := getPullFromES(t.Index) fmt.Println("start...") if err != nil { fmt.Printf("获取es数据失败:%v", err) } //default: // time.Sleep(time.Second * 10) } } time.Sleep(time.Second * 100) } ``` 现象三:read()函数逻辑写在main函数里没有default也不会阻塞。 这其中的关系远离不太懂,不知道为啥会这样。网上找了篇文章看了下: 原文: 其表达意义在于,当多个需要从多个chan中读取或写入时,会先轮询一遍所有的case,然后在所有处于就绪(可读/可写)的chan中随机挑选一个进行读取或写入操作,并执行其语句块。如果所有case都未就绪,则执行default语句,如未提供default语句,则当前协程被阻塞。 如果这个回答解决了第一个现象,后面两个就不知道是为啥了,因为如果和现象二一样延迟启动的话,那channel被add()加入数据,但是第一次取完之后sleep 60秒才会在次添加,在此期间不应该还是case未就绪一直阻塞吗? 因为现象一那种是一直阻塞的。

有疑问加站长微信联系

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:812540095

110 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传