golang 中的 time 包的 Ticker
真实的应用场景是:在测试收包的顺序的时候,加了个 tick 就发现丢包了
那么来看一个应用例子:
package main import (
"fmt"
"runtime"
"time"
) func init() {
runtime.GOMAXPROCS(runtime.NumCPU())
} func main() {
ch := make(chan int, )
go func(ch chan int) {
for {
val := <-ch
fmt.Printf("val:%d\n", val)
}
}(ch) tick := time.NewTicker( * time.Second)
for i := ; i < ; i++ {
select {
case ch <- i:
case <-tick.C:
fmt.Printf("%d: case <-tick.C\n", i)
} time.Sleep( * time.Millisecond)
}
close(ch)
tick.Stop()
}
输出结果如下:
val:0
val:1
val:2
val:3
val:4
val:5
6: case <-tick.C
val:7
val:8
val:9
10: case <-tick.C
val:11
val:12
val:13
val:14
15: case <-tick.C
val:16
val:17
val:18
val:19
问题出在这个select里面:
select {
case ch <- i:
case <-tick.C:
fmt.Printf("%d: case <-tick.C\n", i)
}
[tick.C 介绍说明]当两个 case 条件都满足的时候,运行时系统会通过一个伪随机的算法决定哪个case将会被执行。所以当 tick.C 条件满足的那个循环,有某种概率造成 ch<-i 没有发送(虽然通道两端没有阻塞,满足发送条件)
解决方案1:一旦 tick.C 随机的 case 被随机到,就多执行一次 ch<-i (不体面,如果有多个case就不通用了)
select {
case ch <- i:
case <-tick.C:
fmt.Printf("%d: case <-tick.C\n", i)
ch <- i
}
解决方案2:将tick.C的case单独放到一个select里面,并加入一个default(保证不阻塞)
select {
case ch <- i:
}
select {
case <-tick.C:
fmt.Printf("%d: case <-tick.C\n", i)
default:
}
两种解决方案的输出都是希望的结果:
val:
val:
val:
val:
val:
: case <-tick.C
val:
val:
val:
val:
val:
: case <-tick.C
val:
val:
val:
val:
val:
: case <-tick.C
val:
val:
val:
val:
val:
golang 中的 time 包的 Ticker的更多相关文章
- golang中的reflect包用法
最近在写一个自动生成api文档的功能,用到了reflect包来给结构体赋值,给空数组新增一个元素,这样只要定义一个input结构体和一个output的结构体,并填写一些相关tag信息,就能使用程序来生 ...
- golang中container/list包源码分析
golang源码包中container/list实际上是一个双向链表 提供链表的一些基本操作,下面就结合定义和接口进行下说明 1. 定义 // Element is an element of a l ...
- golang中container/heap包源码分析
学习golang难免需要分析源码包中一些实现,下面就来说说container/heap包的源码 heap的实现使用到了小根堆,下面先对堆做个简单说明 1. 堆概念 堆是一种经过排序的完全二叉树,其中任 ...
- golang中的rpc包用法
RPC,即 Remote Procedure Call(远程过程调用),说得通俗一点就是:调用远程计算机上的服务,就像调用本地服务一样. 我所在公司的项目是采用基于Restful的微服务架构,随着微服 ...
- golang中的context包
标准库的context包 从设计角度上来讲, golang的context包提供了一种父routine对子routine的管理功能. 我的这种理解虽然和网上各种文章中讲的不太一样, 但我认为基本上还是 ...
- golang中net/http包的简单使用
一.介绍 http包提供了http客户端和服务端的实现 Get,Head,Post和PostForm函数发出http.https的请求 程序在使用完回复后必须关闭回复的主体 #简单的访问网站,由于没有 ...
- golang中os/exec包用法
exec包执行外部命令,它将os.StartProcess进行包装使得它更容易映射到stdin和stdout,并且利用pipe连接i/o. 1.func LookPath(file string) ( ...
- 关于Golang中database/sql包的学习
go-sql-driver 请求一个连接的函数有好几种,执行完毕处理连接的方式稍有差别,大致如下: db.Ping() 调用完毕后会马上把连接返回给连接池. db.Exec() 调用完毕后会马上把连接 ...
- Golang中database/sql包
驱动 github.com/go-sql-driver/mysql 请求一个连接的函数有好几种,执行完毕处理连接的方式稍有差别,大致如下: db.Ping() 调用完毕后会马上把连接返回给连接池. d ...
随机推荐
- LeetCode 303. Range Sum Query - Immutable (C++)
题目: Given an integer array nums, find the sum of the elements between indices iand j (i ≤ j), inclus ...
- final发布视频展示博客
Part One [探路者]选题展示视频链接: http://v.youku.com/v_show/id_XMzIxMDM2MTQ1Ng==.html?spm=a2h3j.8428770.341605 ...
- Bing词典vs有道词典比对测试报告——功能篇之核心功能
必应词典vs有道词典 核心功能对比 从应用的UI布局来看,这两款软件的功能如下: 相同 不同 必应词典 词典.例句.翻译 百科 有道词典 词典.例句.翻译 应用 就词典类软件来说,词典是最核心的功能. ...
- 初学Cocos2dx
初学cocos2dx Cocos2dx 中的主要概念包括:应用.导演.场景.层.精灵.动画.动作. Cocos2dx里面的主要类 1.CCObject Object Object Object 是co ...
- 利用Hibernate子查询(in) 得到部分字段(实体类的构造函数)
感人= = 终于弄好了 String hql="select new Shop(s.strid,s.shopname,s.tradearea,s.discountinfo,s.beginti ...
- 0428-Scrum团队成立
------------------------------3.0------------------------------------------ 一.项目要求 5.Scrum团队成立 5.1 团 ...
- Unity3d学习日记(六)
今天在研究怎么在unity中将image上的图片保存到本地,主要参考下面两个链接:Unity Texture2D缩放.UNITY存储图片到本地 结合上述两个链接,我写了如下代码来将缩放后或者改 ...
- Scrum Meeting Beta - 5
Scrum Meeting Beta - 5 NewTeam 2017/12/4 地点:主楼2楼走廊 任务反馈 团队成员 完成任务 计划任务 安万贺 完成了离线状态进入app的功能 实现离线状态读取本 ...
- scrapy-继承默认的user-agent 中间件
class MyUserAgentMiddleware(UserAgentMiddleware): def __init__(self, user_agent): self.user_agent = ...
- Windows 10 正式版原版ISO镜像
Win10正式版32位简体中文版(含家庭版.专业版)文件名: cn_windows_10_multiple_editions_x86_dvd_6846431.isoSHA1:21B824F402927 ...