You are viewing an old version of this page. View the current version.
Compare with Current View Page History
« Previous Version 6 Next »
动态大小的并发安全队列。同时,gqueue也支持固定队列大小,固定队列大小时队列效率和标准库的channel无异。
gqueue
channel
使用场景:
该队列是并发安全的,常用于多goroutine数据通信且支持动态队列大小的场景。
goroutine
使用方式:
import "github.com/gogf/gf/container/gqueue"
接口文档:
https://godoc.org/github.com/gogf/gf/container/gqueue
package main import ( "fmt" "time" "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 } } }
在该示例中,第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
select
使用队列对象公开的Queue.C属性,结合selectIO复用语法实现对队列的读取。
Queue.C
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 ...
glist
gqueue的底层基于glist链表实现动态大小特性,在队列满或者在队列空时读取数据会产生阻塞。
glist是一个并发安全的链表,并可以允许在关闭并发安全特性的时和一个普通的list链表无异,在存储和读取数据时不会发生阻塞。
list