中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

goFrame的隊列gqueue對比channel使用實例分析

發布時間:2022-06-10 09:21:42 來源:億速云 閱讀:162 作者:zzz 欄目:開發技術

本篇內容介紹了“goFrame的隊列gqueue對比channel使用實例分析”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!

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

打印結果

goFrame的隊列gqueue對比channel使用實例分析

優勢

為什么不用標準庫的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一直在消費數據。

goFrame的隊列gqueue對比channel使用實例分析

“goFrame的隊列gqueue對比channel使用實例分析”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

公主岭市| 东平县| 泰兴市| 县级市| 阜平县| 洛川县| 庆阳市| 永兴县| 获嘉县| 嘉定区| 金沙县| 庆元县| 长寿区| 房山区| 黑河市| 江北区| 崇州市| 玉田县| 临沂市| 会昌县| 小金县| 泸水县| 平山县| 常山县| 德惠市| 阿拉善右旗| 元氏县| 大埔区| 冕宁县| 来凤县| 济阳县| 伊吾县| 云阳县| 南京市| 关岭| 华亭县| 武穴市| 抚松县| 玉溪市| 厦门市| 富平县|