热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

goFrame的队列gqueue对比channel使用实例分析

本篇内容介绍了“goFrame的队列gqueue对比channel使用实例分析”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小

本篇内容介绍了“goFrame的队列gqueue对比channel使用实例分析”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

channel

首先明确一下channel的作用:用于go协程间的通信。

go语言最大的特点就是支持高并发:goroutine和channel是支持高并发的重要组成部分。

单纯地将函数并发执行是没有意义的。函数与函数间需要交换数据才能体现并发执行函数的意义。

如果说 goroutine 是Go程序并发的执行体,channel就是它们之间的连接。channel是可以让一个 goroutine 发送特定值到另一个 goroutine 的通信机制。

另外要明确知道go的并发哲学,铭记这句原则:用通信来共享内存,而不要用共享内存来通信。

在搞清楚channel的作用之后我们再来研究GoFrame框架(下文简称gf)中gqueue的特点。

gqueue

概念

队列 gqueue 动态大小的并发安全队列

gqueue也可以设置为固定大小的队列,固定大小时和标准库channel没区别。

简单来说channel实现的功能gqueue也能实现。

使用场景:

gqueue是并发安全的,常用于多个goroutine数据通信且支持动态队列大小的场景

代码演示

package main
import (
   "fmt"
   "github.com/gogf/gf/container/gqueue"
   "github.com/gogf/gf/os/gtimer"
   "time"
)
func main() {
   //实例化gqueue
   q := gqueue.New()
   //数据生产者 每隔1秒想队列写入1条数据
   gtimer.SetInterval(time.Second, func() {
      nowStr := time.Now().String()
      q.Push(nowStr)
   })
   //3秒后关闭队列
   gtimer.SetTimeout(time.Second*3, func() {
      fmt.Println("关闭队列")
      q.Close()
   })
   // 消费者 不停的从队列中取值输出到终端中
   for {
      if v := q.Pop(); v != nil {
         fmt.Println("消费者接收:", v)
      } else {
         break
      }
   }
}

打印结果

goFrame的队列gqueue对比channel使用实例分析

优势

为什么不用标准库的channel,要用gqueue呢?

  • gqueue的使用比channel更灵活,channel有队列大小的限制,而gqueue队列支持动态大小

  • channel的读写性能确实非常高,但是channel创建的时候需要初始化内存,初始化操作效率非常低;而gqueue的创建效率非常高,gqueue是动态创建内存。

底层实现

gqueue的底层实现是基于glist实现动态大小的特性,在队列满或者队列空时读取数据会产生阻塞。

glist是一个并发安全的链接,支持关闭并发安全的特性,当关闭并发安全的特性时和普通链表无异,在存储和读取数据时,不会产生阻塞。

阻止进程销毁

select{}的作用可以阻止进程销毁

package main
import (
   "fmt"
   "github.com/gogf/gf/container/gqueue"
   "github.com/gogf/gf/os/gtime"
   "github.com/gogf/gf/os/gtimer"
   "time"
)
func main() {
   //实例化队列
   queue := gqueue.New()
   // 生产者每隔1秒钟向队列写入一条数据
   gtimer.SetInterval(time.Second, func() {
      queue.Push(gtime.Now().String())
   })
   //消费者 常驻内存一直接收生产者的数据
   for {
      select {
      case v := <-queue.C: //C是 chan interface{}
         if v != nil {
            fmt.Println("消费者:", v)
         } else {
            return
         }
      }
   }
}

运行结果

如下图所示,select{}可以阻止进程销毁,gtimer一直在生产数据,而for循环中的select一直在消费数据。

goFrame的队列gqueue对比channel使用实例分析

“goFrame的队列gqueue对比channel使用实例分析”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注编程笔记网站,小编将为大家输出更多高质量的实用文章!


推荐阅读
  • 目录实现效果:实现环境实现方法一:基本思路主要代码JavaScript代码总结方法二主要代码总结方法三基本思路主要代码JavaScriptHTML总结实 ... [详细]
  • 本文讨论了使用差分约束系统求解House Man跳跃问题的思路与方法。给定一组不同高度,要求从最低点跳跃到最高点,每次跳跃的距离不超过D,并且不能改变给定的顺序。通过建立差分约束系统,将问题转化为图的建立和查询距离的问题。文章详细介绍了建立约束条件的方法,并使用SPFA算法判环并输出结果。同时还讨论了建边方向和跳跃顺序的关系。 ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • Go Cobra命令行工具入门教程
    本文介绍了Go语言实现的命令行工具Cobra的基本概念、安装方法和入门实践。Cobra被广泛应用于各种项目中,如Kubernetes、Hugo和Github CLI等。通过使用Cobra,我们可以快速创建命令行工具,适用于写测试脚本和各种服务的Admin CLI。文章还通过一个简单的demo演示了Cobra的使用方法。 ... [详细]
  • 开发笔记:实验7的文件读写操作
    本文介绍了使用C++的ofstream和ifstream类进行文件读写操作的方法,包括创建文件、写入文件和读取文件的过程。同时还介绍了如何判断文件是否成功打开和关闭文件的方法。通过本文的学习,读者可以了解如何在C++中进行文件读写操作。 ... [详细]
  • 本文讨论了如何使用IF函数从基于有限输入列表的有限输出列表中获取输出,并提出了是否有更快/更有效的执行代码的方法。作者希望了解是否有办法缩短代码,并从自我开发的角度来看是否有更好的方法。提供的代码可以按原样工作,但作者想知道是否有更好的方法来执行这样的任务。 ... [详细]
  • 李逍遥寻找仙药的迷阵之旅
    本文讲述了少年李逍遥为了救治婶婶的病情,前往仙灵岛寻找仙药的故事。他需要穿越一个由M×N个方格组成的迷阵,有些方格内有怪物,有些方格是安全的。李逍遥需要避开有怪物的方格,并经过最少的方格,找到仙药。在寻找的过程中,他还会遇到神秘人物。本文提供了一个迷阵样例及李逍遥找到仙药的路线。 ... [详细]
  • 本文主要解析了Open judge C16H问题中涉及到的Magical Balls的快速幂和逆元算法,并给出了问题的解析和解决方法。详细介绍了问题的背景和规则,并给出了相应的算法解析和实现步骤。通过本文的解析,读者可以更好地理解和解决Open judge C16H问题中的Magical Balls部分。 ... [详细]
  • 本文介绍了如何在给定的有序字符序列中插入新字符,并保持序列的有序性。通过示例代码演示了插入过程,以及插入后的字符序列。 ... [详细]
  • JavaSE笔试题-接口、抽象类、多态等问题解答
    本文解答了JavaSE笔试题中关于接口、抽象类、多态等问题。包括Math类的取整数方法、接口是否可继承、抽象类是否可实现接口、抽象类是否可继承具体类、抽象类中是否可以有静态main方法等问题。同时介绍了面向对象的特征,以及Java中实现多态的机制。 ... [详细]
  • Java String与StringBuffer的区别及其应用场景
    本文主要介绍了Java中String和StringBuffer的区别,String是不可变的,而StringBuffer是可变的。StringBuffer在进行字符串处理时不生成新的对象,内存使用上要优于String类。因此,在需要频繁对字符串进行修改的情况下,使用StringBuffer更加适合。同时,文章还介绍了String和StringBuffer的应用场景。 ... [详细]
  • XML介绍与使用的概述及标签规则
    本文介绍了XML的基本概念和用途,包括XML的可扩展性和标签的自定义特性。同时还详细解释了XML标签的规则,包括标签的尖括号和合法标识符的组成,标签必须成对出现的原则以及特殊标签的使用方法。通过本文的阅读,读者可以对XML的基本知识有一个全面的了解。 ... [详细]
  • Python正则表达式学习记录及常用方法
    本文记录了学习Python正则表达式的过程,介绍了re模块的常用方法re.search,并解释了rawstring的作用。正则表达式是一种方便检查字符串匹配模式的工具,通过本文的学习可以掌握Python中使用正则表达式的基本方法。 ... [详细]
  • 本文详细介绍了Spring的JdbcTemplate的使用方法,包括执行存储过程、存储函数的call()方法,执行任何SQL语句的execute()方法,单个更新和批量更新的update()和batchUpdate()方法,以及单查和列表查询的query()和queryForXXX()方法。提供了经过测试的API供使用。 ... [详细]
  • 本文介绍了Android 7的学习笔记总结,包括最新的移动架构视频、大厂安卓面试真题和项目实战源码讲义。同时还分享了开源的完整内容,并提醒读者在使用FileProvider适配时要注意不同模块的AndroidManfiest.xml中配置的xml文件名必须不同,否则会出现问题。 ... [详细]
author-avatar
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有