基本使用

使用Queue.Pop

package main

import (
    "fmt"
    "time"
    "github.com/gogf/gf/v2/os/gtimer"
    "github.com/gogf/gf/v2/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
        }
    }

	// 第3秒时关闭队列,这时程序立即退出,因此结果中只会打印2秒的数据。 执行后,输出结果为:
	// Output:
	// Push: 2021-09-07 14:03:00
	//  Pop: 2021-09-07 14:03:00
	// Push: 2021-09-07 14:03:01
	//  Pop: 2021-09-07 14:03:01
}

使用Queue.C

package main

import (
	"context"
	"fmt"
	"time"

	_ "github.com/gogf/gf/contrib/drivers/mysql/v2"
	"github.com/gogf/gf/v2/container/gqueue"
	"github.com/gogf/gf/v2/os/gctx"
	"github.com/gogf/gf/v2/os/gtime"
	"github.com/gogf/gf/v2/os/gtimer"
)

func main() {
	queue := gqueue.New()
	gtimer.AddTimes(gctx.GetInitCtx(), time.Second, 3, func(ctx context.Context) {
		queue.Push(gtime.Now().String())
	})
	for {
		select {
		case queueItem := <-queue.C:
			fmt.Println(queueItem)

		case <-time.After(3 * time.Second):
			fmt.Println("timeout, exit loop")
			return
		}
	}
}

元素入队/出队

package main

import (
    "fmt"
    "time"
    "github.com/gogf/gf/v2/os/gtimer"
    "github.com/gogf/gf/v2/container/gqueue"
)

func main() {
	q := gqueue.New()

	for i := 0; i < 10; i++ {
		q.Push(i)
	}

	fmt.Println(q.Pop())
	fmt.Println(q.Pop())
	fmt.Println(q.Pop())

	// Output:
	// 0
	// 1
	// 2 
}

队列长度

package main

import (
    "fmt"
    "time"
    "github.com/gogf/gf/v2/os/gtimer"
    "github.com/gogf/gf/v2/container/gqueue"
)

func main() {
	q := gqueue.New()

	q.Push(1)
	q.Push(2)

	fmt.Println(q.Len())
	// size是len方法的别称
	fmt.Println(q.Size())

	// May Output:
	// 2
	// 2
}

队列关闭

package main

import (
    "fmt"
    "time"
    "github.com/gogf/gf/v2/os/gtimer"
    "github.com/gogf/gf/v2/container/gqueue"
)

func main() {
	q := gqueue.New()

	for i := 0; i < 10; i++ {
		q.Push(i)
	}

	fmt.Println(q.Pop())
	q.Close()
	fmt.Println(q.Pop())
	fmt.Println(q.Len())

	// Output:
	// 0
	// <nil>
	// 0
}

gqueueglist

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

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



Content Menu

  • No labels

2 Comments

  1. 队列实际在web服务中应该怎么使用呢? 能否像laravel 一样?

  2. 2.3.2的版本。

    fmt.Println("-------")
    q := gqueue.New()
    q.Push(1)
    q.Push(2)
    fmt.Println(q.Len())
    fmt.Println(q.Size())
    <-q.C
    fmt.Println(q.Len())
    fmt.Println(q.Size())
    fmt.Println("-------")


    输出结果:
    -------
    2
    2
    2
    2
    -------

    2.2.5的版本。
    同样的代码
    输出结果是:
    -------
    2
    2
    1
    1
    -------
    老版本的代码符合预期,这个应该是个BUG吧。