網站首頁 編程語言 正文
1、Channels 定義
通道是一種支持多類型的管道,您可以通過它使用通道運算符 <- 發送和接收值。
數據沿箭頭方向流動。
ch <- v // Send v to channel ch. v := <-ch // Receive from ch, and // assign value to v.
與 maps 和 slices 一樣,通道必須在使用前創建:
ch := make(chan int)
默認情況下,發送和接收阻塞,直到另一方準備就緒。
這允許 goroutines 在沒有顯式鎖或條件變量的情況下進行同步。
package main import "fmt" func sum(s []int, c chan int) { ?? ?sum := 0 ?? ?for _, v := range s { ?? ??? ?sum += v ?? ?} ?? ?c <- sum // send sum to c } func main() { ?? ?s := []int{7, 2, 8, -9, 4, 0} ?? ?c := make(chan int) ?? ?go sum(s[:len(s)/2], c) ?? ?go sum(s[len(s)/2:], c) ?? ?x, y := <-c, <-c // receive from c ?? ?fmt.Println(x, y, x+y) }
2、chan 常用操作
- 無緩沖區: 存入讀取一次,存入后未取,再存入就會堵塞,同樣未存,就取也會堵塞。
- 有緩沖區: 只有當緩沖區滿了,才會堵塞存;只有緩沖區空時,才會堵塞取。
- len(channel) 返回緩沖區現有數據長度
- cap(channel) 返回緩沖區的大小
- close(channel) 關閉 channel,關閉后,讀取不到數據。如下,如果其他協程關掉 channel 則會跳出循環
3、帶緩沖chan實現消息隊列功能
// 監測數據結構體 type Msg struct { ?? ?Timestamp?? ?int64 ?? ?Content?? ??? ?string?? ??? ? } // 用 chan 模擬隊列,隊列的元素為 Msg 類型 var SyncQueen chan Msg // 必須初始化才能使用。初始化一個容量為1024的 chan。chan 滿時會阻塞 func init() { ?? ?SyncQueen = make(chan Msg, 1024) }
// 隊列消費者 func Consumer() { ?? ?defer func() { ?? ??? ?if err := recover(); err != nil { ?? ??? ??? ?fmt.Println(err) ?? ??? ?} ?? ?}() ?? ?for { ?? ??? ?// chan 內無消息則阻塞 ?? ??? ?msg := <-SyncQueen ?? ??? ?fmt.Println(msg.Content) ?? ?} }
// 隊列生產者 func Producer() { ?? ?for { ?? ??? ?msg := Msg(time.now().Unix(), "hello") ?? ??? ? ?? ??? ?// 發送消息到 chan ?? ??? ?SyncQueen <- msg ?? ??? ?time.Sleep(2 time.Second) ?? ?} }
重點
多協程使用chan是并發安全的,以下展示一個簡單的例子:
// 定義類型為 int 的 chan var chanNums chan int // chan 的消費者,用戶后續多協程 // 目的:數組里存儲了10000個數字,多個協程并行計算后,把和加起來 func consumer(sum *int) int { ?? ?for { ?? ??? ?v := <-chanNums ?? ??? ?*sum += v ?? ?} } //------------------------------------- func main() { ?? ?var a [10000]int ?? ?for i := 0; i < 10000; i++ { ?? ??? ?a[i] = i + 1 ?? ?} ?? ?chanNums = make(chan int, 10000) ?? ?for i := 0; i < 10000; i++ { ?? ??? ?chanNums <- (i + 1) ?? ?} ?? ?var s1, s2, s3, s4, s5 int = 0, 0, 0, 0, 0 ?? ?go consumer(&s1) ?? ?go consumer(&s2) ?? ?go consumer(&s3) ?? ?go consumer(&s4) ?? ?go consumer(&s5) ?? ?for { ?? ??? ?time.Sleep(5 * time.Second) ?? ??? ?break ?? ?} ?? ?fmt.Println("s1=", s1, "s2=", s2, "s3=", s3, "s4=", s4, "s5=", s5) ?? ?fmt.Println("sum=", s1+s2+s3+s4+s5) } // 輸出 s1= 10818438 s2= 12073966 s3= 9044041 s4= 11509634 s5= 6558921 sum= 50005000
原文鏈接:https://blog.csdn.net/sepnineth/article/details/129226758
- 上一篇:沒有了
- 下一篇:沒有了
相關推薦
- 2022-02-26 Hutool cn.hutool.core.bean.BeanException: Set valu
- 2022-10-14 SpringCloud組件之Gateway微服務網關
- 2023-10-10 ant tree拖動排序 實現同級拖動 和 跨級拖動
- 2022-08-01 GoLand一鍵上傳項目到遠程服務器的方法步驟_Golang
- 2022-12-01 可定制React自動完成搜索組件Turnstone實現示例_React
- 2022-07-16 Spring MVC重定向和轉發
- 2022-12-28 Android?ViewPager2?+?Fragment?聯動效果的實現思路_Android
- 2022-02-15 H5移動端大轉盤抽獎插件, 簡單、易用、無依賴
- 欄目分類
-
- 最近更新
-
- 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同步修改后的遠程分支