go实现简单的chan
文章目录
- 借助sync.Cond可以实现简单的chan
- golang的chan的原理
借助sync.Cond可以实现简单的chan
为避免内存频繁开辟,队列最佳实现是循环队列(为图方便,这里没有采用)。阅读本文前请了解队列和条件变量的知识
package mainimport ("fmt""strconv""sync""time"
)type Queue struct {queue []stringcond1 *sync.Condcond2 *sync.Condsize int
}func NewQueue(size int) *Queue {var mux sync.Mutexreturn &Queue{cond1: sync.NewCond(&mux),cond2: sync.NewCond(&mux),size: size,}
}// producer
func (q *Queue) Enqueue(str string) {for {q.cond1.L.Lock()if len(q.queue) >= q.size {q.cond2.Wait()}if len(q.queue) >= q.size {q.cond1.L.Unlock()continue}q.queue = append(q.queue, str)q.cond1.L.Unlock()q.cond1.Signal()break}
}// consumer
func (q *Queue) Dequeue() string {str := ""for {q.cond1.L.Lock()if len(q.queue) == 0 {q.cond1.Wait()}// 为防止多个协程接收到条件成立信号,必须判断if len(q.queue) == 0 {q.cond1.L.Unlock()continue}str = q.queue[0]q.queue = q.queue[1:]q.cond1.L.Unlock()q.cond2.Signal()break}return str
}
func main() {q := NewQueue(10)go func() {for i := 0; i < 1000; i++ {q.Enqueue(strconv.Itoa(i))fmt.Println("写数据:",i)}}()go func() {for {time.Sleep(time.Millisecond * 200)val := q.Dequeue()fmt.Println("读数据:",val)}}()time.Sleep(time.Hour)
}
golang的chan的原理
- chan创建在堆中,返回指针
- 使用环形队列作为缓存区
- 每次操作都要加锁,并更新sendx或recvx(队列的头尾指针)
- 缓存满,进入等待队列,让出cpu
- 被唤醒后,重新进入G执行队列
go实现简单的chan相关推荐
- 制坯系列-Golang专题-chan
<制坯系列-Golang专题>:chan作为协程之间通信的重要方式,是替代内存共享的最佳通信方式,本文对基本原理和关键知识点做简单介绍 chan底层数据结构 type hchan stru ...
- go chan简单使用
chan在go中是一个通道有可读可写的chan,也存在只读只写的chan,通过共享内存而实现通信 chan 注意点: 在关闭chan后再关闭chan 会出现panic 关闭chan后可以继续进行取值, ...
- golang源码分析:调度器chan调度
golang调度机制chan调度 golang的调度策略中,碰见阻塞chan就会将该chan放入到阻塞的g中,然后再等待该chan被唤醒,这是golang调度器策略的主动调度策略之一,其中还有其他的主 ...
- Maven 让事情变得简单
http://www-128.ibm.com/developerworks/cn/java/j-maven/ 尽管 Ant 对于构建 Java 程序而言是事实上的标准工具,但这个工具在许多方面都不胜任 ...
- Golang实现简单爬虫框架(4)——队列实现并发任务调度
前言 在上一篇文章<Golang实现简单爬虫框架(3)--简单并发版>中我们实现了一个最简单并发爬虫,调度器为每一个Request创建一个goroutine,每个goroutine往Wor ...
- php defer,PHP 协程:Go + Chan + Defer
Swoole4提供了强大的PHP CSP协程编程模式.底层提供了3个关键词,可以方便地实现各类功能. 关键词 go :创建一个协程 chan :创建一个通道 defer :延迟任务,在协程退出时执行, ...
- php简单还是go简单_PHP转Golang一些感想
由于某些原因参与到团队Golang项目的开发中,之前开发主要用的PHP,现在Golang用了也有较长一段时间了,就想着写篇博客分享下现在的一些感想,缕一缕Golang的优缺点. 缺点1:没有异常,Em ...
- Nutanix:将IT基础架构“隐形”,让云更简单
Nutanix以超融合被全球用户熟知,作为超融合的先驱者,该公司凭借着领先的技术以及在产品与服务上不断的精益求精,获得了许多企业客户的认可.虽然"超融合"标签显眼,但在云的大趋势下 ...
- 深入解析 Kubebuilder:让编写 CRD 变得更简单
原文连接:https://developer.aliyun.com/article/719215 作者 | 刘洋(炎寻) 阿里云高级开发工程师 导读:自定义资源 CRD(Custom Resource ...
- 使用go语言GUI库实现对mp3文件的播放1(简单的播放mp3文件)
使用go语言GUI库实现对mp3文件的播放1(简单的播放mp3文件) 使用beep播放mp3文件(10num) 使用go语言GUI库fyne实现音乐播放器 要是想使用go语言实现播放mp3需要借助be ...
最新文章
- 盘点那些最常用的Linux命令,都应该记熟!
- 线上直播丨KDD 2021预训练Workshop,谷歌MSRA等5位顶尖研究者参与研讨
- 操作系统原理:进程 PV 操作如何计算?全网最全三种前驱图计算类型总结
- MySQL之算术表达式、聚合函数及GROUP BY 与 HANVING 等函数的应用
- /dev/tty和/dev/console
- 业务规则方法的基本原则
- rancher的使用感受以及与k8s的对比
- hyperterminal停止工作_hyper terminal超级终端最新下载
- 海风的Linux开发环境介绍
- 如何有效的获得高质量的大规模标注数据?
- MATLAB-数字图像处理 量化
- ubuntu/deepin安装配置mysql
- php 电子签字,电子签名和电子签字的区别
- 十大api接口平台(接口商)
- favicon.ico制作
- 秋招提前批已来,万字长文教你如何增加面试大厂的成功率
- 51单片机开发入门(3)-IO口应用
- QTextEdit和QTextDocument(ZZ)
- DirectDraw基础篇(学东西还是基础的好哦!)
- 逆序链表从m到n位置
热门文章
- rs485接口上下拉_RS485使用注意事项(上下拉电阻)
- Projector学习笔记
- 随机数字表法计算机分配,随机数字表法
- jq 清除ajax缓存,js清除浏览器缓存的几种方法
- fatal error C1083:/fatal error C1010: 错误处理
- 张朝阳“削藩”后,搜狐会走向何处?
- 铁通dns服务器地址是多少,电信/网通/铁通dns服务器地址大全
- 【BZOJ 3097】 Hash Killer I
- Java使用map接收时间格式是Wed Sep 14 00:00:00 CST 2022这种解决办法
- Java项目名前有红色感叹号怎么解决