2019独角兽企业重金招聘Python工程师标准>>>

What you are wasting today is tomorrow for those who died yesterday; what you hate now is the future you can not go back.

你所浪费的今天是昨天死去的人奢望的明天; 你所厌恶的现在是未来的你回不去的曾经。

select介绍

select语句用于从多个发送/接收通道操作中进行选择。直到发送/接收操作之一准备就绪,select停止阻塞。如果多个操作准备就绪,随机选择其中一个。语法与switch类似,只是每个case语句都是一个通道操作。

让我们直接进入一些代码,以便更好地理解。

package mainimport ("fmt""time"
)func server1(ch chan string) {time.Sleep(2 * time.Second)ch <- "from server1"
}
func server2(ch chan string) {time.Sleep(1 * time.Second)ch <- "from server2"}
func main() {output1 := make(chan string)output2 := make(chan string)go server1(output1)go server2(output2)select {case s1 := <-output1:fmt.Println(s1)case s2 := <-output2:fmt.Println(s2)}// time.Sleep(4*time.Second)
}

解释: main程启动两个goroutine来向通道中发送数据,select负责监听(一直处于阻塞状态),等待其中 一个goroutine发送数据成功,select 立即停止阻塞并接收数据后退出select。

试想:如果我们将代码中的注释部分开启,程序的输出内容有没有变化?

防止阻塞或default

当case没有准备好(获取到数据)时, default语句会执行,这样就防止了select的阻塞状态出现。

package mainimport ("fmt""time"
)
func process(in chan string) {for {time.Sleep(4 * time.Second)in <- "数据写入"}
}func main(){in := make(chan string)go process(in)for{time.Sleep(2*time.Second)select{case str := <-in :fmt.Println("接受到数据:",str)default:fmt.Println("等待中...")}}}

当mian程启动一个goroutine向通道中写数据后, main程开始for监听in 通道, sleep 2秒后, <-in 未能读取到数据,select 打印default内的数据, 等到再次sleep后in通道传递数据。

死锁

当没有数据发送时,仅仅从通道中来接收数据,程序将会永久的阻塞, 因此会导致死锁。

func main() {  ch := make(chan string)select {case <-ch:}
}

select从nil channel中接收数据

package mainimport "fmt"func main() {var ch chan stringselect {case v := <-ch:fmt.Println("received value", v)default:fmt.Println("default case executed")}
}

总结: select 中default语句是默认执行, 防止程序的阻塞产生。

Random Select

如果case语句中有多个通道发送来数据, 那select将会如何输出?

package mainimport (  "fmt""time"
)func server1(ch chan string) {  ch <- "from server1"
}
func server2(ch chan string) {  ch <- "from server2"}
func main() {  output1 := make(chan string)output2 := make(chan string)go server1(output1)go server2(output2)time.Sleep(2 * time.Second)  // 使所有goroutine的channel写入数据select {case s1 := <-output1:fmt.Println(s1)case s2 := <-output2:fmt.Println(s2)}
}

select将会随机的从中选择输出, 因此输出结果可能不相同。

空select

我们上面说到, select直到case(在没有default的前提下)中接收到数据时,才会停止阻塞。

那么空select会发生什么?

package mainfunc main() {  select {}
}

程序永久性阻塞(引发死锁)。

转载于:https://my.oschina.net/90design/blog/1635718

Golang并发(五) - Select相关推荐

  1. golang 并发demo 写入 redis

    原文链接:golang 并发demo 写入 redis 源代码: package mainimport ("fmt""runtime""strconv ...

  2. ​Golang 并发编程指南

    分享 Golang 并发基础库,扩展以及三方库的一些常见问题.使用介绍和技巧,以及对一些并发库的选择和优化探讨. go 原生/扩展库 提倡的原则 不要通过共享内存进行通信;相反,通过通信来共享内存. ...

  3. Golang并发模型:轻松入门协程池

    goroutine是非常轻量的,不会暂用太多资源,基本上有多少任务,我们可以开多少goroutine去处理.但有时候,我们还是想控制一下. 比如,我们有A.B两类工作,不想把太多资源花费在B类务上,而 ...

  4. Golang并发模型:合理退出并发协程

    goroutine作为Golang并发的核心,我们不仅要关注它们的创建和管理,当然还要关注如何合理的退出这些协程,不(合理)退出不然可能会造成阻塞.panic.程序行为异常.数据结果不正确等问题.这篇 ...

  5. 4种Golang并发操作中常见的死锁情形

    摘要:什么是死锁,在Go的协程里面死锁通常就是永久阻塞了,你拿着我的东西,要我先给你然后再给我,我拿着你的东西又让你先给我,不然就不给你.我俩都这么想,这事就解决不了了. 本文分享自华为云社区< ...

  6. golang并发编程之Ticker

    golang并发编程之Ticker Timer只执行一次,Ticker可以周期的执行 icker是一个定时触发的计时器 它会以一个间隔(interval)往channel发送一个事件(当前时间) 而c ...

  7. Golang并发模型:轻松入门流水线FAN模式

    前一篇文章<Golang并发模型:轻松入门流水线模型>,介绍了流水线模型的概念,这篇文章是流水线模型进阶,介绍FAN-IN和FAN-OUT,FAN模式可以让我们的流水线模型更好的利用Gol ...

  8. Golang并发:再也不愁选channel还是选锁

    周末又到了,为大家准备了一份实用干货:如何使用channel和Mutex解决并发问题,利用周末的好时光,配上音乐,思考一下吧?. 来,问自己个问题:面对并发问题,是用channel解决,还是用Mute ...

  9. 暗刺,高并发五个利器

    文章目录 一.前言 二.缓存 2.1 缓存本质 + 缓存分类 + 缓存三大特征 + 三种淘汰算法 + 根据业务场景设计过期时间 2.1.1 缓存本质 2.1.2 缓存分类(本地缓存+分布式缓存=分级缓 ...

  10. 【高并发】高并发五个利器(缓存、限流、降级、熔断、隔离)

    文章目录 文章目录 一.前言 二.缓存 2.1 缓存本质 + 缓存分类 + 缓存三大特征 + 三种淘汰算法 + 根据业务场景设计过期时间 2.2 本地缓存(进程内缓存) 2.3 分布式缓存 2.4 缓 ...

最新文章

  1. 写给小白看的线程和进程,高手勿入
  2. golang中的sync.Map
  3. 【过程记录】springboot中使用EhcacheCache+mybatis
  4. Python中os库的使用
  5. 端口以及服务常用cmd
  6. mysql pid_mysql pid文件是什么用途
  7. 【java】java 理解JDK中UUID的底层实现
  8. 关于解决运行sql文件时,找不到MySQL默认编码utf8mb4的问题
  9. javaScript函数封装
  10. 拓端tecdat|R语言解释生存分析中危险率和风险率的变化
  11. 速达财务管理软件使用方法
  12. 实验一 MATLAB数字图像处理基本操作
  13. 【阿里网盘】深度学习与Pytorch视频教程
  14. Delphi的日期时间格式
  15. 迭代器Iterator的用法
  16. 一步教你超简单设置Android Studio背景图片
  17. phpstudy后门代码利用及分析
  18. 肽基脯氨酰异构酶底物:1926163-51-0,WFY-pSer-PR-AMC
  19. 【Python爬虫】| XPANX获取抖音APP小视屏
  20. python--socket(套接字/插口)

热门文章

  1. RabbitMQ(五) 订阅发布者模式介绍以及代码实现
  2. c语言 -1%4,**************
  3. 笨方法python3_“笨方法”学Python3,习题 43 。
  4. Java多线程与并发 面试十大常考题目。
  5. python设计模式2-工厂方法模式
  6. 源码分析 | 深度解密Go语言之context
  7. RabbitMQ消息确认以及return机制
  8. JVM性能优化之堆区域OOM问题
  9. 关于spring cloud的几个核心组件
  10. 关于kafka的几个问题