網(wǎng)站首頁 編程語言 正文
一、Go語言通道基礎(chǔ)概念
1.channel產(chǎn)生背景
?? ?線程之間進行通信的時候,會因為資源的爭奪而產(chǎn)生竟態(tài)問題,為了保證數(shù)據(jù)交換的正確性,必須使用互斥量給內(nèi)存進行加鎖,go語言并發(fā)的模型是CSP,提倡通過通信共享內(nèi)存,而不是通過共享內(nèi)存而實現(xiàn)通信,通道恰巧滿足這種需求。
2.channel工作方式
?? ?channel
類似與一個隊列,滿足先進先出的規(guī)則,嚴(yán)格保證收發(fā)數(shù)據(jù)的順序,每一個通道只能通?過固定類型的數(shù)據(jù)如果通道進行大型結(jié)構(gòu)體、字符串的傳輸,可以將對應(yīng)的指針傳進去,盡量的節(jié)省空間
二、通道使用語法
1.通道的聲明與初始化
?? ?//定義一個通道對象使用,其中int可以換為自己需要的類型 ?? ?var a chan int ? ?? ?//初始化只有一個位置的通道(第一個參數(shù)代表通道類型,第二個參數(shù)代表通道有幾個位置) ?? ?//位置存滿后新的數(shù)據(jù)將存不進來(阻塞) ?? ?a = make(chan int,1)
2.將數(shù)據(jù)放入通道內(nèi)
- 取出數(shù)據(jù)使用操作符 <-操作符右是輸入變量,操作符左是通道代表數(shù)據(jù)流入通道內(nèi)
代碼如下:
? ?// 聲明一個通道 ?? ?var a chan int ?? ??? ?a <- 5
3.從通道內(nèi)取出數(shù)據(jù)
- ?取出數(shù)據(jù)也使用操作符 <-操作符右是通道,操作符左是接受變量
代碼如下:
?//聲明一個通道類型 ?? ?var a chan int ?? ?fmt.Println("未初始化的通道", a) ?? ?a = make(chan int) ?? ?// wg.Add(1) ?? ?go func(a chan int) { ?? ??? ?// defer wg.Done() ?? ??? ?for { ?? ??? ??? ?x := <-a ?? ??? ??? ?fmt.Println("接收到了數(shù)據(jù):", x) ?? ??? ?} ?? ?}(a)
4.關(guān)閉通道close
?? ?如果通道重復(fù)關(guān)閉或者關(guān)閉一個沒有初始化的通道就會拋出錯誤
?close(a)//a為待關(guān)閉的通道
在并發(fā)函數(shù)中一次關(guān)閉通道代碼如下:
// 互斥鎖對象 var once sync.Once //并發(fā)函數(shù) //這個函數(shù)的目的是將a通道內(nèi)數(shù)據(jù)乘以10發(fā)送到通道b內(nèi) func f2(a <-chan int, b chan<- int) { ?? ?defer wg.Done() ?? ?for { ?? ??? ?x, ok := <-a ?? ??? ?if !ok { ?? ??? ??? ?break ?? ??? ?} ?? ??? ?fmt.Println(x) ?? ??? ?b <- x * 10 ?? ?} ?? ?// 確保b通道只關(guān)閉一次 ?? ?once.Do(func() { ?? ??? ?close(b) ?? ?}) }
三、單項通道及通道的狀態(tài)分析
1.單項輸出通道
?? ?var b <-chan int
2.單項輸入通道
?? ?var b chan<- int
示例函數(shù):
//單項通道一般做函數(shù)參數(shù),作為一種規(guī)范防止通道混用 //此函數(shù)完成的功能是將a內(nèi)的數(shù)據(jù)乘以10放入通道b內(nèi) func f2(a <-chan int, b chan<- int) { ?? ?for { ?? ??? ?x, ok := <-a ?? ??? ?if !ok { ?? ??? ??? ?break ?? ??? ?} ?? ??? ?fmt.Println(x) ?? ??? ?b <- x * 10 ?? ?} }
3.通道的狀態(tài)
channel | nil未初始化 | 空通道 | 滿通道 | 非空 |
---|---|---|---|---|
接收 | 阻塞 | 阻塞 | 接收值 | 接收值 |
發(fā)送 | 阻塞 | 發(fā)送值 | 阻塞 | 發(fā)送值 |
關(guān)閉 | panic | 關(guān)閉成功 | 關(guān)閉成功 | 關(guān)閉成功 |
關(guān)閉后返回的數(shù)據(jù) | panic | 返回0值 | 數(shù)據(jù)讀完后返回零值 | 數(shù)據(jù)讀完返回零值 |
四、通道死鎖原因分析
注意以下情況:
在使用通道的時候,從以上表格可知有時會進入阻塞狀態(tài),結(jié)合waitGroup,如果在主函數(shù)等待使用通道的函數(shù)執(zhí)行結(jié)束,而使用通道的函數(shù)并且通道陷入阻塞狀態(tài),如果有其他函數(shù)對其進行喚醒則不會死鎖,如果沒有其他函數(shù)可以對其進行喚醒則會拋出死鎖異常。
總結(jié):
通道將數(shù)據(jù)隔離在每一份通道內(nèi),在并發(fā)的情況下可以很好的使用數(shù)據(jù),當(dāng)然要熟悉通道阻塞的幾種情況,避免死鎖異常。
原文鏈接:https://blog.csdn.net/apple_51931783/article/details/122532742
相關(guān)推薦
- 2023-01-02 Python利用socket實現(xiàn)多進程的端口掃描器_python
- 2022-05-26 Flutter開發(fā)實現(xiàn)底部留言板_Android
- 2022-05-21 詳解C#枚舉中使用Flags特性_C#教程
- 2022-09-05 詳解apache編譯安裝httpd-2.4.54及三種風(fēng)格的init程序特點和區(qū)別_Linux
- 2022-06-30 C語言詳細(xì)分析講解流程控制語句用法_C 語言
- 2023-11-13 【云原生】python獲取docker stats 容器cpu使用率
- 2022-10-11 主從同步中斷(sql_thread)問題一例
- 2023-03-27 react使用.env文件管理全局變量的方法_React
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細(xì)win安裝深度學(xué)習(xí)環(huán)境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認(rèn)證信息的處理
- Spring Security之認(rèn)證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡單動態(tài)字符串(SD
- arthas操作spring被代理目標(biāo)對象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠(yuǎn)程分支