網站首頁 編程語言 正文
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 } } } 復制代碼
打印結果
優勢
為什么不用標準庫的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一直在消費數據。
總結
原文鏈接:https://juejin.cn/post/7103502362429358116
相關推薦
- 2023-02-04 詳解如何在C#中接受或拒絕Excel中的修訂_C#教程
- 2022-03-04 如何在uni-app中選擇一個合適的UI組件庫
- 2022-03-31 Python機器學習應用之基于線性判別模型的分類篇詳解_python
- 2023-05-20 linux?shell輸出換行簡單實例_linux shell
- 2022-06-02 基于Android?Flutter編寫貪吃蛇游戲_Android
- 2022-12-19 批處理bat腳本獲取打包發布問題記錄_DOS/BAT
- 2022-04-28 python中對列表的刪除和添加方法詳解_python
- 2022-11-16 生產redisson延時隊列不消費問題排查解決_Redis
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支