goFrame的gqueue与channe的区别

目录
  • channel
  • gqueue
    • 概念
  • 优势
  • 底层实现
  • 阻止进程销毁
  • 总结

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
      }
   }
}

打印结果:

优势

为什么不用标准库的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一直在消费数据。

总结

通过这篇文章,我们知道了channel的概念和作用。也知道了gqueue的底层实现和特点,以及gqueue和channel的对比。两者各有什么特点。

到此这篇关于goFrame的gqueue与channe的区别的文章就介绍到这了,更多相关goFrame的gqueue内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • 深入理解golang chan的使用

    目录 前言 见真身 结构体 发送数据 接收数据 上手 定义 发送与接收 前言 之前在看golang多线程通信的时候, 看到了go 的管道. 当时就觉得这玩意很神奇, 因为之前接触过的不管是php, java, Python, js, c等等, 都没有这玩意, 第一次见面, 难免勾起我的好奇心. 所以就想着看一看它具体是什么东西. 很明显, 管道是go实现在语言层面的功能, 所以我以为需要去翻他的源码了. 虽然最终没有翻到C的层次, 不过还是受益匪浅. 见真身 结构体 要想知道他是什么东西, 没什

  • grpool goroutine池协程管理

    目录 前言 名词概念 使用示例 踩坑之旅 常犯的错误 分析原因 使用grpool 错误代码 正确代码 总结 前言 goroutine协程非常轻量级,这也是为什么go支持高并发,但是goroutine频繁创建销毁对GC的压力比较大. grpool的作用就是复用goroutine,减少频繁创建销毁的性能消耗. 名词概念 Pool: goroutine池,用于管理若干可复用的goroutine协程资源 Worker: 池对象中参与任务执行的goroutine,一个worker可以执行若干个job,直到

  • golang基于websocket通信tcp keepalive研究记录

    目录 为什么有tcp Keepalive? tcp Keepalive是否默认开启? 如何设置tcp keepalive? 在Linux内核设置 golang websocket 客户端默认怎么处理tcp keepalive? golang websocket 服务器默认怎么处理tcp keepalive? 为什么有tcp Keepalive? 服务器和客户端建立tcp连接以后,客户端/服务器如何知道对方是否挂掉了? 这时候TCP协议提出一个办法,当客户端端等待超过一定时间后自动给服务端发送一个

  • golang redis中Pipeline通道的使用详解

    目录 一.pipeline出现的背景 二.pipeline的用法 pipeline命令的使用 goredis库连接客户端 package client import (     "github.com/go-redis/redis"     "github.com/sirupsen/logrus" ) var MainRDS *redis.Client func init() {     ConnectRedis() } func ConnectRedis() {

  • goFrame的gqueue与channe的区别

    目录 channel gqueue 概念 优势 底层实现 阻止进程销毁 总结 channel 首先明确一下channel的作用:用于go协程间的通信. go语言最大的特点就是支持高并发:goroutine和channel是支持高并发的重要组成部分. 单纯地将函数并发执行是没有意义的.函数与函数间需要交换数据才能体现并发执行函数的意义. 如果说 goroutine 是Go程序并发的执行体,channel就是它们之间的连接.channel是可以让一个 goroutine 发送特定值到另一个 goro

  • goFrame的队列gqueue对比channel使用详解

    目录 channel gqueue 概念 使用场景: 代码演示 打印结果 优势 底层实现 阻止进程销毁 运行结果 总结 channel 首先明确一下channel的作用:用于go协程间的通信. go语言最大的特点就是支持高并发:goroutine和channel是支持高并发的重要组成部分. 单纯地将函数并发执行是没有意义的.函数与函数间需要交换数据才能体现并发执行函数的意义. 如果说 goroutine 是Go程序并发的执行体,channel就是它们之间的连接.channel是可以让一个 gor

  • 浅谈Linux信号机制

    一.信号列表 root@ubuntu:# kill -l  1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL 5) SIGTRAP  6) SIGABRT 7) SIGBUS 8) SIGFPE 9) SIGKILL 10) SIGUSR1 11) SIGSEGV 12) SIGUSR2 13) SIGPIPE 14) SIGALRM 15) SIGTERM 16) SIGSTKFLT 17) SIGCHLD 18) SIGCONT 19) SIGSTOP 20)

  • GoFrame glist 基础使用和自定义遍历

    目录 join 序列化和反序列化 基础概念 GoFrame框架(下文简称gf)提供的数据类型,比如:字典gmap.数组garray.集合gset.队列gqueue.树形结构gtree.链表glist都是支持设置并发安全开关的. 支持设置并发安全开关这也是gf提供的常用数据类型和原生数据类型非常重要的区别 今天和大家分享gf框架的glist详解: 基本使用 glist的使用场景是:双向链表 通过PushBack向链表尾部插入数据 通过PushFront向链表头部插入数据 通过InsertBefor

  • GoFrame gmap遍历hashmap listmap treemap使用技巧

    目录 先说结论 map类型 使用技巧 基础概念 对比sync.Map 基础使用 合并 merge 序列化 过滤空值 键值对反转 Flip 出栈(随机出栈) 总结 文章比较硬核,爆肝2千多字,除了hashmap.listmap.treemap使用技巧阅读还有使用gmap的踩坑之旅,阅读大约需要5~10分钟. 先说结论 map类型 一图胜千言: 实例化示例: hashMap := gmap.New(true) listMap := gmap.NewListMap(true) treeMap := g

  • GoFrame框架garray对比PHP的array优势

    目录 打印结果 打印结果 打印结果 打印结果: 打印结果 打印结果 打印结果 写过PHP的同学都知道 PHP的数组Array非常好用,特别灵活. 我在写PHP之前使用Java做安卓开发,在接触PHP的数组Array之后,直呼太香了! 而在学习Go基础知识的时候了解到Go的数组和PHP的数组并不一样:从一定程度上讲,Go的slice切片类型和PHP的数组array比较像(不固定长度.引用类型.动态扩容等),但是在开发使用中远远不像PHP的array灵活. 初识GoFrame 最近在使用基于Go语言

  • GoFrame gredis缓存DoVar Conn连接对象 自动序列化

    目录 整体介绍 小技巧 基本使用 HSET/HGETALL操作 HMSET/HMGET操作 基本使用 Send批量指令 订阅/发布 map存取 打印结果 struct存取 打印结果 上一篇文章为大家介绍了 GoFrame gcache使用实践 | 缓存控制 淘汰策略 ,得到了大家积极的反馈. 后续几篇文章再接再厉,仍然为大家介绍GoFrame框架缓存相关的知识点,以及自己项目使用中的一些总结思考,GoFrame框架下文简称gf. 这篇文章比较硬核,爆肝2千字,阅读大约需要5~8分钟. 详细的介绍

  • jQuery和AngularJS的区别浅析

    最近一直在研究angularjs,最大的感受就是它和之前的jQuery以及基于jQuery的各种库设计理念完全不同,如果不能认识到这点而对于之前做jQuery开发的程序员,去直接学习angularjs的话,很可能学了很久还不知道这个东西能用来干什么以及怎么使用,怎么和UI进行结合等问题,在stackoverflow上找到一篇关于这方面的文章,阅读之后颇有收获,在此基础上将它译成中文,以求抛砖引玉大家一同学习. 原问题:假如我熟悉利用jQuery去开发客户端应用,那么我怎么上手angularjs,

  • Angular中ng-bind和ng-model的区别实例详解

    ng-bind和ng-model的区别 AngularJS的数据绑定有ng-bind和ng-model,一般用于如下: <input ng-model="object.xxx"> <span ng-bind="object.xxx"></span> ng-bind是单向绑定,由作用于$scope到view层,且在HTML控件(HTML控件有:input.select.button和textarea)中不可显示. ng-model是

  • 正则表达式中test、exec、match的区别介绍及括号的用法

    test.exec.match的简单区别 1.test test 返回 Boolean,查找对应的字符串中是否存在模式. var str = "1a1b1c"; var reg = new RegExp("1.", ""); alert(reg.test(str)); // true 2.exec exec 查找并返回当前的匹配结果,并以数组的形式返回. var str = "1a1b1c"; var reg = new Re

随机推荐