網(wǎng)站首頁 編程語言 正文
定義channel管道
定義一個channel時,也需要定義發(fā)送到管道的值類型。channel可以使用內(nèi)置的make()函數(shù)來創(chuàng)建:
var ch = make(chan int) //等價于:make(chan Type,0) var ch = make(chan Type,capacity)
channel管道塞值和取值
ch <- 666 //向ch管道塞入666
<- ch // 向ch管道接收值,并丟棄
x := <-ch //向ch管道中接收數(shù)據(jù),并復制給x
x, ok := <-ch //向ch管道中接收數(shù)據(jù),并復制給x,同時檢查通道是否已關閉或者是否為空
當capacity=0時,channel管道是無緩沖阻塞讀寫,
當capacity>0時,channel管道有緩沖,是非阻塞的,直到寫滿capacity個元素才阻塞寫入。
?
注意:默認情況下,channel接收和發(fā)送數(shù)據(jù)都是阻塞的,除非另一端已經(jīng)準備好,這樣就使得goroutine同步變得更加簡單,而不需要顯示的lock。
通過channel管道實現(xiàn)同步,和數(shù)據(jù)交互
package main import ( "fmt" "time" ) func main() { //創(chuàng)建channel ch := make(chan string) defer fmt.Println("主協(xié)程也結束") go func() { defer fmt.Println("子協(xié)程調(diào)用完畢") for i := 0; i < 2; i++ { fmt.Println("子協(xié)程 i = ", i) time.Sleep(time.Second) } ch <- "我是子協(xié)程,要工作完畢" }() str := <-ch //沒有數(shù)據(jù)前,阻塞 fmt.Println("str = ", str) }
無緩沖的channel
ch := make(chan int, 0)
package main import ( "fmt" "time" ) func main() { //創(chuàng)建一個無緩存的channel ch := make(chan int, 0) //len(ch)緩沖區(qū)剩余數(shù)據(jù)個數(shù), cap(ch)緩沖區(qū)大小 fmt.Printf("len(ch) = %d, cap(ch)= %d\n", len(ch), cap(ch)) //新建協(xié)程 go func() { for i := 0; i < 10000; i++ { fmt.Printf("子協(xié)程:i = %d\n", i) ch <- i //往chan寫內(nèi)容 time.Sleep(1 * time.Second) } }() go func() { for { num := <-ch //讀管道中內(nèi)容,沒有內(nèi)容前,阻塞 fmt.Println("num = ", num) } }() for { } }
有緩沖的channel管道
ch := make(chan int, 3)
package main import ( "fmt" "time" ) func main() { //創(chuàng)建一個有緩存的channel ch := make(chan int, 3) //len(ch)緩沖區(qū)剩余數(shù)據(jù)個數(shù), cap(ch)緩沖區(qū)大小 fmt.Printf("len(ch) = %d, cap(ch)= %d\n", len(ch), cap(ch)) //新建協(xié)程 go func() { for i := 0; i < 10; i++ { ch <- i //往chan寫內(nèi)容 fmt.Printf("子協(xié)程[%d]: len(ch) = %d, cap(ch)= %d\n", i, len(ch), cap(ch)) } }() //延時 time.Sleep(2 * time.Second) for i := 0; i < 10; i++ { num := <-ch //讀管道中內(nèi)容,沒有內(nèi)容前,阻塞 fmt.Println("num = ", num) } }
關閉channel管道
close(ch)
package main import ( "fmt" ) func main() { //創(chuàng)建一個無緩存的channel ch := make(chan int, 3) //len(ch)緩沖區(qū)剩余數(shù)據(jù)個數(shù), cap(ch)緩沖區(qū)大小 fmt.Printf("len(ch) = %d, cap(ch)= %d\n", len(ch), cap(ch)) //新建協(xié)程 go func() { for i := 0; i < 10000; i++ { fmt.Printf("子協(xié)程:i = %d\n", i) ch <- i //往chan寫內(nèi)容 //time.Sleep(1 * time.Second) if i >10 { close(ch) break } } }() go func() { for { if num, ok := <-ch; ok == true { fmt.Println("num = ", num) } else { //管道關閉 break } } }() for { } }
單向channel管道,讀寫分離
chan<- ?表示數(shù)據(jù)進入管道,只寫
<-chan 表示數(shù)據(jù)從管道出來,只讀
注意:雙向可轉為單向,單向不可轉為雙向
package main //"fmt" func main() { //創(chuàng)建一個channel, 雙向的 ch := make(chan int) //雙向channel能隱式轉換為單向channel var writeCh chan<- int = ch //只能寫,不能讀 var readCh <-chan int = ch //只能讀,不能寫 writeCh <- 666 //寫 //<-writeCh //err, invalid operation: <-writeCh (receive from send-only type chan<- int) <-readCh //讀 //readCh <- 666 //寫, err, invalid operation: readCh <- 666 (send to receive-only type <-chan int) //單向無法轉換為雙向 //var ch3 chan int = writeCh //cannot use writeCh (type chan<- int) as type chan int in assignment }
管道消費者生產(chǎn)者模型
package main import ( "fmt" ) //此通道只能寫,不能讀 func producer(out chan<- int) { for i := 0; i < 10; i++ { out <- i * i //寫入 } close(out) //關閉 } //此channel只能讀,不能寫 func consumer(data <-chan int) { for num := range data { fmt.Println("num = ", num) } } func main() { //創(chuàng)建一個雙向通道 ch := make(chan int) //生產(chǎn)者,生產(chǎn)數(shù)字,寫入channel //新開一個協(xié)程 go producer(ch) //channel傳參,引用傳遞 //消費者,從channel讀取內(nèi)容,打印 consumer(ch) }
原文鏈接:https://www.cnblogs.com/guyouyin123/p/13986351.html
相關推薦
- 2023-06-19 C++開放封閉原則示例解析_C 語言
- 2022-09-07 C語言函數(shù)調(diào)用堆棧詳情分析_C 語言
- 2022-04-24 解決redis在linux上的部署的問題_Redis
- 2022-04-27 jQuery實現(xiàn)消息滾動播放效果_jquery
- 2022-03-17 C語言判斷數(shù)是否為素數(shù)與素數(shù)輸出_C 語言
- 2022-03-07 C++中簡單的文本文件輸入/輸出示例詳解_C 語言
- 2022-05-22 Flutter應用框架搭建之屏幕適配詳解_Android
- 2023-07-28 el-table 默認勾選數(shù)據(jù)
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細win安裝深度學習環(huán)境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結構-簡單動態(tài)字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支