goFrame的gqueue與channe的區(qū)別
channel
首先明確一下channel的作用:用于go協(xié)程間的通信。
go語言最大的特點就是支持高并發(fā):goroutine和channel是支持高并發(fā)的重要組成部分。
單純地將函數(shù)并發(fā)執(zhí)行是沒有意義的。函數(shù)與函數(shù)間需要交換數(shù)據(jù)才能體現(xiàn)并發(fā)執(zhí)行函數(shù)的意義。
如果說 goroutine 是Go程序并發(fā)的執(zhí)行體,channel就是它們之間的連接。channel是可以讓一個 goroutine 發(fā)送特定值到另一個 goroutine 的通信機制。
另外要明確知道go的并發(fā)哲學,銘記這句原則:用通信來共享內存,而不要用共享內存來通信。
在搞清楚channel的作用之后我們再來研究GoFrame框架(下文簡稱gf)中gqueue的特點。
gqueue
概念
隊列 gqueue 動態(tài)大小的并發(fā)安全隊列
gqueue也可以設置為固定大小的隊列,固定大小時和標準庫channel沒區(qū)別。簡單來說channel實現(xiàn)的功能gqueue也能實現(xiàn)。
使用場景:
gqueue是并發(fā)安全的,常用于多個goroutine數(shù)據(jù)通信且支持動態(tài)隊列大小的場景
代碼演示:
package main
import (
"fmt"
"github.com/gogf/gf/container/gqueue"
"github.com/gogf/gf/os/gtimer"
"time"
)
func main() {
//實例化gqueue
q := gqueue.New()
//數(shù)據(jù)生產(chǎn)者 每隔1秒想隊列寫入1條數(shù)據(jù)
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
}
}
}打印結果:

優(yōu)勢
為什么不用標準庫的channel,要用gqueue呢?
- gqueue的使用比channel更靈活,channel有隊列大小的限制,而gqueue隊列支持動態(tài)大小
- channel的讀寫性能確實非常高,但是channel創(chuàng)建的時候需要初始化內存,初始化操作效率非常低;而gqueue的創(chuàng)建效率非常高,gqueue是動態(tài)創(chuàng)建內存。
底層實現(xiàn)
gqueue的底層實現(xiàn)是基于glist實現(xiàn)動態(tài)大小的特性,在隊列滿或者隊列空時讀取數(shù)據(jù)會產(chǎn)生阻塞。
glist是一個并發(fā)安全的鏈接,支持關閉并發(fā)安全的特性,當關閉并發(fā)安全的特性時和普通鏈表無異,在存儲和讀取數(shù)據(jù)時,不會產(chǎn)生阻塞。
阻止進程銷毀
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()
// 生產(chǎn)者每隔1秒鐘向隊列寫入一條數(shù)據(jù)
gtimer.SetInterval(time.Second, func() {
queue.Push(gtime.Now().String())
})
//消費者 常駐內存一直接收生產(chǎn)者的數(shù)據(jù)
for {
select {
case v := <-queue.C: //C是 chan interface{}
if v != nil {
fmt.Println("消費者:", v)
} else {
return
}
}
}
}運行結果:
如下圖所示,select{}可以阻止進程銷毀,gtimer一直在生產(chǎn)數(shù)據(jù),而for循環(huán)中的select一直在消費數(shù)據(jù)。

總結
通過這篇文章,我們知道了channel的概念和作用。也知道了gqueue的底層實現(xiàn)和特點,以及gqueue和channel的對比。兩者各有什么特點。
到此這篇關于goFrame的gqueue與channe的區(qū)別的文章就介紹到這了,更多相關goFrame的gqueue內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
golang xorm及time.Time自定義解決json日期格式的問題
這篇文章主要介紹了golang xorm及time.Time自定義解決json日期格式的問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-12-12
golang調用c實現(xiàn)的dll接口細節(jié)分享
這篇文章主要介紹了golang調用c實現(xiàn)的dll接口細節(jié)分享,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2021-05-05
Go條件控制語句詳解(if-else、switch和select)
條件語句用于檢查一個條件是否為真,并根據(jù)條件的真假來決定是否執(zhí)行相應的代碼,下面這篇文章主要給大家介紹了關于Go條件控制語句(if-else、switch和select)的相關資料,需要的朋友可以參考下2024-03-03

