文章目录

  • 借助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的原理

  1. chan创建在堆中,返回指针
  2. 使用环形队列作为缓存区
  3. 每次操作都要加锁,并更新sendx或recvx(队列的头尾指针)
  4. 缓存满,进入等待队列,让出cpu
  5. 被唤醒后,重新进入G执行队列

go实现简单的chan相关推荐

  1. 制坯系列-Golang专题-chan

    <制坯系列-Golang专题>:chan作为协程之间通信的重要方式,是替代内存共享的最佳通信方式,本文对基本原理和关键知识点做简单介绍 chan底层数据结构 type hchan stru ...

  2. go chan简单使用

    chan在go中是一个通道有可读可写的chan,也存在只读只写的chan,通过共享内存而实现通信 chan 注意点: 在关闭chan后再关闭chan 会出现panic 关闭chan后可以继续进行取值, ...

  3. golang源码分析:调度器chan调度

    golang调度机制chan调度 golang的调度策略中,碰见阻塞chan就会将该chan放入到阻塞的g中,然后再等待该chan被唤醒,这是golang调度器策略的主动调度策略之一,其中还有其他的主 ...

  4. Maven 让事情变得简单

    http://www-128.ibm.com/developerworks/cn/java/j-maven/ 尽管 Ant 对于构建 Java 程序而言是事实上的标准工具,但这个工具在许多方面都不胜任 ...

  5. Golang实现简单爬虫框架(4)——队列实现并发任务调度

    前言 在上一篇文章<Golang实现简单爬虫框架(3)--简单并发版>中我们实现了一个最简单并发爬虫,调度器为每一个Request创建一个goroutine,每个goroutine往Wor ...

  6. php defer,PHP 协程:Go + Chan + Defer

    Swoole4提供了强大的PHP CSP协程编程模式.底层提供了3个关键词,可以方便地实现各类功能. 关键词 go :创建一个协程 chan :创建一个通道 defer :延迟任务,在协程退出时执行, ...

  7. php简单还是go简单_PHP转Golang一些感想

    由于某些原因参与到团队Golang项目的开发中,之前开发主要用的PHP,现在Golang用了也有较长一段时间了,就想着写篇博客分享下现在的一些感想,缕一缕Golang的优缺点. 缺点1:没有异常,Em ...

  8. Nutanix:将IT基础架构“隐形”,让云更简单

    Nutanix以超融合被全球用户熟知,作为超融合的先驱者,该公司凭借着领先的技术以及在产品与服务上不断的精益求精,获得了许多企业客户的认可.虽然"超融合"标签显眼,但在云的大趋势下 ...

  9. 深入解析 Kubebuilder:让编写 CRD 变得更简单

    原文连接:https://developer.aliyun.com/article/719215 作者 | 刘洋(炎寻) 阿里云高级开发工程师 导读:自定义资源 CRD(Custom Resource ...

  10. 使用go语言GUI库实现对mp3文件的播放1(简单的播放mp3文件)

    使用go语言GUI库实现对mp3文件的播放1(简单的播放mp3文件) 使用beep播放mp3文件(10num) 使用go语言GUI库fyne实现音乐播放器 要是想使用go语言实现播放mp3需要借助be ...

最新文章

  1. 盘点那些最常用的Linux命令,都应该记熟!
  2. 线上直播丨KDD 2021预训练Workshop,谷歌MSRA等5位顶尖研究者参与研讨
  3. 操作系统原理:进程 PV 操作如何计算?全网最全三种前驱图计算类型总结
  4. MySQL之算术表达式、聚合函数及GROUP BY 与 HANVING 等函数的应用
  5. /dev/tty和/dev/console
  6. 业务规则方法的基本原则
  7. rancher的使用感受以及与k8s的对比
  8. hyperterminal停止工作_hyper terminal超级终端最新下载
  9. 海风的Linux开发环境介绍
  10. 如何有效的获得高质量的大规模标注数据?
  11. MATLAB-数字图像处理 量化
  12. ubuntu/deepin安装配置mysql
  13. php 电子签字,电子签名和电子签字的区别
  14. 十大api接口平台(接口商)
  15. favicon.ico制作
  16. 秋招提前批已来,万字长文教你如何增加面试大厂的成功率
  17. 51单片机开发入门(3)-IO口应用
  18. QTextEdit和QTextDocument(ZZ)
  19. DirectDraw基础篇(学东西还是基础的好哦!)
  20. 逆序链表从m到n位置

热门文章

  1. rs485接口上下拉_RS485使用注意事项(上下拉电阻)
  2. Projector学习笔记
  3. 随机数字表法计算机分配,随机数字表法
  4. jq 清除ajax缓存,js清除浏览器缓存的几种方法
  5. fatal error C1083:/fatal error C1010: 错误处理
  6. 张朝阳“削藩”后,搜狐会走向何处?
  7. 铁通dns服务器地址是多少,电信/网通/铁通dns服务器地址大全
  8. 【BZOJ 3097】 Hash Killer I
  9. Java使用map接收时间格式是Wed Sep 14 00:00:00 CST 2022这种解决办法
  10. Java项目名前有红色感叹号怎么解决