Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

基本介绍

动态大小的并发安全队列。同时,gqueue也支持固定队列大小,固定队列大小时队列效率和标准库的channel无异。

使用场景

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

使用方式

Code Block
languagego
import "github.com/gogf/gf/v2/container/gqueue"

接口文档

https://godocpkg.org/githubgo.com/gogf/gf/container/gqueue

使用示例

示例1,基本使用

package main import ( "fmt" "time" "

dev/github.com/gogf/gf/

os/gtimer" "github.com/gogf/gf/container/gqueue" ) func main() { q := gqueue.New() // 数据生产者,每隔1秒往队列写数据 gtimer.SetInterval(time.Second, func() { v := gtime.Now().String() q.Push(v) fmt.Println("Push:", v) }) // 3秒后关闭队列 gtimer.SetTimeout(3*time.Second, func() { q.Close() }) // 消费者,不停读取队列数据并输出到终端 for { if v := q.Pop(); v != nil { fmt.Println(" Pop:", v) } else { break } } }

v2/container/gqueue

相关文档

Children Display
alltrue
excerptTypesimple

在该示例中,第3秒时关闭队列,这时程序立即退出,因此结果中只会打印2秒的数据。 执行后,输出结果为:

Push: 2018-09-07 14:03:00
 Pop: 2018-09-07 14:03:00
Push: 2018-09-07 14:03:01
 Pop: 2018-09-07 14:03:01

示例2,结合select语法使用

使用队列对象公开的Queue.C属性,结合selectIO复用语法实现对队列的读取。

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:
                if v != nil {
                    fmt.Println(v)
                } else {
                    return
                }
        }
    }
}

执行后,输出结果为:

2019-01-23 20:42:01
2019-01-23 20:42:02
2019-01-23 20:42:03
2019-01-23 20:42:04
2019-01-23 20:42:05
2019-01-23 20:42:06
...

gqueueglist

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

glist是一个并发安全的链表,并可以允许在关闭并发安全特性的时和一个普通的list链表无异,在存储和读取数据时不会发生阻塞。

gqueuechannel

gqueue与标准库channel的性能基准测试,其中每一次基准测试的b.N值均为20000000,以保证动态队列存取一致防止deadlock:

goos: linux
goarch: amd64
pkg: github.com/gogf/gf/container/gqueue
Benchmark_Gqueue_StaticPushAndPop-4       20000000            84.2 ns/op
Benchmark_Gqueue_DynamicPush-4            20000000             164 ns/op
Benchmark_Gqueue_DynamicPop-4             20000000             121 ns/op
Benchmark_Channel_PushAndPop-4            20000000            70.0 ns/op
PASS

可以看到标准库的channel的读写性能是非常高的,但是创建的时候由于需要初始化内存,因此创建channel的时候效率非常非常低(初始化即分配内存),并且受到队列大小的限制,写入的数据不能超过指定的队列大小。gqueue使用起来比channel更加灵活,不仅创建效率高(动态分配内存),不受队列大小限制(也可限定大小)。


Panel
titleContent Menu

Table of Contents