golang关键字select的三个例子, time.After模拟socket/心跳超时
golang关键字select的三个例子, time.After模拟socket/心跳超时
例子1 select会随机选择一个可执行的case
// 这个例子主要说明select是随机选择一个可执行的case
func main() {
// 定义两个chan, 用于存储数据
// 由于我打算提前把数据存进去, 所以定义缓冲区为10
chan1 := make(chan int, 10)
chan2 := make(chan int, 10)
// 在两个chan中都放入10个数据
for i := 0; i < 10; i++ {
chan1 <- i
}
for i := 0; i < 10; i++ {
chan2 <- i
}
// 启动一个for循环, 无限循环
// select的作用:
// select会随机选择一个case, 判断该case后面的语句是否可以执行
// 如果可以执行, 进入case的代码块中, 执行代码块
// 如果不能只能, 则随机挑选另一个case来进行判断
// select会持续这个随机挑选判断的过程, 直到某一个case可以被执行, 并且执行它
// 也就是说select会阻塞在这里, 直到选择了某一个case
// 特别说明: 判断的顺序是随机的, 看看第一个, 看看第二个, 再看看第二个, 再看看第一个
// 这个和switch-case是不一样的
fmt.Println("即将进入select")
fmt.Println("你会发现chan 1和chan 2是随机打印的, 没有规 ")
fmt.Println("验证了select是随机选择")
for {
select {
case num1 := <-chan1:
{
fmt.Printf("从chan 1中取出了数据, 这是第%d次选择case 1\n", num1)
}
case num2 := <-chan2:
{
fmt.Printf("从chan 2中取出了数据, 这是第%d次选择case 2\n", num2)
}
case <-time.After(time.Second * 5):
{
// 请忽略这个case, 仅仅是为了退出程序
// time.After的用法将在case 2中讲解
fmt.Println("5秒了, 程序退出")
return
}
}
}
}

例子2 select会阻塞, 直到某一个case可以执行 && time.After的用法
// 这个例子主要验证select会阻塞, 直到某一个case可以执行
// 同时也会说明time.After的用法
func main() {
// 创建一个通道, 在for循环中会从中取值
dataChan := make(chan int)
// 启动一个go程
go func() {
// 13秒之后, 我往这个dataChan中放入一个数据
// 这个数据是什么不重要, 重要的是我放入了一个数据
time.Sleep(time.Second * 13)
fmt.Println("13秒到了, 往dataChan放入一个数据")
dataChan <- 1
}()
// 这个go程只是用来打印时间和退出程序的, 对测试内容没有任何影响
go func() {
for i := 0; ; i++ {
fmt.Printf("%d秒\n", i+1)
time.Sleep(time.Second * 1)
if i == 22 {
fmt.Println("测试结束, 程序退出")
os.Exit(0)
}
}
}()
// 启动一个for循环, 无限循环
for {
// 每次循环从这里开始
fmt.Println("-----我是select, 我开始阻塞选择啦-----")
select {
case <-dataChan:
{
// 判断是否能从dataChan这个channel中取出数据来
// 显然前13秒是取不出来的, 因为没有人给他放数据
fmt.Println("13秒到了, 从dataChan中取出了数据")
fmt.Println("注意观察, 下一次select的时候, time.After会重新计时5秒")
}
case <-time.After(time.Second * 5):
// time.After的作用:
// 每次执行到select时
// 这个time.After会开始计时
// (如果到了)5秒后, 就会生产出一个数据, select就会认为这个case可以执行, 选择这个case
// 如果没有到5秒, select就选择了其他case, 那么这个计时器会清零
// 下一次循环中, 会重新进行5秒计时
fmt.Println("5秒过去啦, time.After生产出了数据, select选择了第二个case")
}
}
}

例子3 用select来判断socket/心跳超时
// 这个例子是用select来判断socket/心跳超时
func main() {
// 用这个channel来模拟socket输入, 输入数据或者心跳
socketChan := make(chan int)
go func() {
// 模拟输入/心跳, 每5秒输入一个数据/接收到心跳
for i := 0; i < 2; i++ {
time.Sleep(time.Second * 5)
fmt.Printf("socket: 第%d个5秒到了, 我输入一个数据\n", i+1)
socketChan <- i
}
// 10秒后, socket崩溃, 不再输入数据/不再发送心跳
time.Sleep(time.Millisecond * 1)
fmt.Println("socket: 我崩溃啦, 没有办法继续输入数据了")
fmt.Println("开始计算超时时间, 预计10秒后超时")
}()
// 这个go程只是用来打印时间和退出程序的, 对测试内容没有任何影响
go func() {
for i := 0; ; i++ {
fmt.Printf("%d秒\n", i+1)
time.Sleep(time.Second * 1)
if i == 21 {
fmt.Println("测试结束, 程序退出")
os.Exit(0)
}
}
}()
// 启动一个for循环, 无限循环
for {
fmt.Println("-----我是select, 我开始阻塞选择啦-----")
select {
case num := <-socketChan:
{
fmt.Printf("我是select: 我收到了socket输入 是第%d次\n", num+1)
}
case <-time.After(time.Second * 10):
{
// 超时时间设定为10秒
fmt.Println("我是select: 连续10秒都没有收到socket输入, 超时了")
return
}
}
}
}

golang关键字select的三个例子, time.After模拟socket/心跳超时的更多相关文章
- golang 自学系列(三)—— if,for,channel
golang 自学系列(三)-- if,for,channel 一般情况下,if 语句跟大多数语言的 if 判断语句一样,根据一个 boolean 表达式结果来执行两个分支逻辑. 但凡总是有例外,go ...
- go中的关键字-select
1. select的使用 定义:在golang里头select的功能与epoll(nginx)/poll/select的功能类似,都是坚挺IO操作,当IO操作发生的时候,触发相应的动作. 1.1 一些 ...
- golang的select实现原理剖析
写在最前面 select为golang提供了多路IO复用机制,和其他IO复用一样,用于检测是否有读写事件是否ready. 本文将介绍一下golang的select的用法和实现原理. 实现原理 gola ...
- css通用小笔记02——浮动、清除(三个例子)
css中通常会用到浮动与清除,也是一个必须掌握的知识点,概念性的东西不多说,下面举几个例子,来说明它的用法:1.文字环绕效果 2.多个div并排显示 3.清除浮动(默认显示) 一.文字环绕效果: h ...
- 统计学习方法笔记--EM算法--三硬币例子补充
本文,意在说明<统计学习方法>第九章EM算法的三硬币例子,公式(9.5-9.6如何而来) 下面是(公式9.5-9.8)的说明, 本人水平有限,怀着分享学习的态度发表此文,欢迎大家批评,交流 ...
- calling c++ from golang with swig--windows dll (三)
calling c++ from golang with swig--windows dll 三 使用动态链接库(DLL)主要有两种方式:一种通过链接导入库,在代码中直接调用DLL中的函数:另一种借助 ...
- keras神经网络三个例子
keras构造神经网络,非常之方便!以后就它了.本文给出了三个例子,都是普通的神经网络 例一.离散输出,单标签.多分类 例二.图像识别,单标签.多分类.没有用到卷积神经网络(CNN) 例三.时序预测, ...
- Golang中map的三种声明方式和简单实现增删改查
package main import ( "fmt" ) func main() { test3 := map[string]string{ "one": & ...
- golang的select典型用法
golang 的 select 的功能和 select, poll, epoll 相似, 就是监听 IO 操作,当 IO 操作发生时,触发相应的动作. 示例: ch1 := make (chan in ...
随机推荐
- Python Requests-学习笔记(4)-定制请求头和POST
定制请求头 如果你想为请求添加HTTP头部,只要简单地传递一个 dict 给 headers 参数就可以了. import jsonurl = 'https://api.github.com/some ...
- 一、华为模拟器eNSP下载与安装教程
简单介绍一下 eNSP: eNSP是一款由华为提供的免费的图形化网络仿真工具平台,它将完美呈现真实设备实景(包括华为最新的ARG3路由器和X7系列的交换机),支持大型网络模拟,让你有机会在没有真实设备 ...
- 关于TOMCAT中的两个Web.xml
关于TOMCAT中的两个Web.xml (2013-01-19 17:32:57) 转载▼ 标签: 杂谈 初学JAVA web开发.. Servlet定义的时候,我发现在${catalina.ho ...
- HttpClient之Get请求和Post请求示例
HttpClient之Get请求和Post请求示例 博客分类: Java综合 HttpClient的支持在HTTP/1.1规范中定义的所有的HTTP方法:GET, HEAD, POST, PUT, ...
- 数据结构和算法(Golang实现)(6)简单入门Golang-并发、协程和信道
并发.协程和信道 Golang语言提供了go关键字,以及名为chan的数据类型,以及一些标准库的并发锁等,我们将会简单介绍一下并发的一些概念,然后学习这些Golang特征知识. 一.并发介绍 我们写程 ...
- 008-进制-C语言笔记
008-进制-C语言笔记 学习目标 1.[掌握]include预处理指令 2.[掌握]多文件开发 3.[了解]认识进制 4.[掌握]进制之间的互相转换 5.[掌握]原码,反码,补码 6.[掌握]位运算 ...
- Python数据可视化---pygal模块
目录 pygal模块 安装pygal模块 pygal模块介绍 柱状图 单列柱状图 堆叠柱状图 横向柱状图 折线图 简单折线图 纵向折线图 堆叠折线图 饼状图 简单饼状图 多级饼状图 圆环图 半圆图 雷 ...
- 【MyBatis深入剖析】应用分析与最佳实践
##### 文章目标1. 了解ORM框架的发展历史,了解MyBatis特性2. 掌握MyBatis编程式开发方法和核心对象3. 掌握MyBatis核心配置含义4. 掌握MyBatis的高级用法与扩展方 ...
- Upload-Labs 实验操作记录
0x01 安装 下载:https://github.com/c0ny1/upload-labs 环境:简单搭建phpstudy环境即可,记得在upload-labs根目录下创建该文件夹 0x02 文件 ...
- CLDAPReflectionDDoS(CLDAP反射放大攻击)
CLDAP Reflection DDoS 0x01 LDAP: 全称为Lightweight Directory Access Protocol,即轻量目录访问协议,基于X.500标准: 目录服务就 ...