網站首頁 編程語言 正文
定義channel管道
定義一個channel時,也需要定義發送到管道的值類型。channel可以使用內置的make()函數來創建:
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管道中接收數據,并復制給x
x, ok := <-ch //向ch管道中接收數據,并復制給x,同時檢查通道是否已關閉或者是否為空
當capacity=0時,channel管道是無緩沖阻塞讀寫,
當capacity>0時,channel管道有緩沖,是非阻塞的,直到寫滿capacity個元素才阻塞寫入。
?
注意:默認情況下,channel接收和發送數據都是阻塞的,除非另一端已經準備好,這樣就使得goroutine同步變得更加簡單,而不需要顯示的lock。
通過channel管道實現同步,和數據交互
package main import ( "fmt" "time" ) func main() { //創建channel ch := make(chan string) defer fmt.Println("主協程也結束") go func() { defer fmt.Println("子協程調用完畢") for i := 0; i < 2; i++ { fmt.Println("子協程 i = ", i) time.Sleep(time.Second) } ch <- "我是子協程,要工作完畢" }() str := <-ch //沒有數據前,阻塞 fmt.Println("str = ", str) }
無緩沖的channel
ch := make(chan int, 0)
package main import ( "fmt" "time" ) func main() { //創建一個無緩存的channel ch := make(chan int, 0) //len(ch)緩沖區剩余數據個數, cap(ch)緩沖區大小 fmt.Printf("len(ch) = %d, cap(ch)= %d\n", len(ch), cap(ch)) //新建協程 go func() { for i := 0; i < 10000; i++ { fmt.Printf("子協程:i = %d\n", i) ch <- i //往chan寫內容 time.Sleep(1 * time.Second) } }() go func() { for { num := <-ch //讀管道中內容,沒有內容前,阻塞 fmt.Println("num = ", num) } }() for { } }
有緩沖的channel管道
ch := make(chan int, 3)
package main import ( "fmt" "time" ) func main() { //創建一個有緩存的channel ch := make(chan int, 3) //len(ch)緩沖區剩余數據個數, cap(ch)緩沖區大小 fmt.Printf("len(ch) = %d, cap(ch)= %d\n", len(ch), cap(ch)) //新建協程 go func() { for i := 0; i < 10; i++ { ch <- i //往chan寫內容 fmt.Printf("子協程[%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 //讀管道中內容,沒有內容前,阻塞 fmt.Println("num = ", num) } }
關閉channel管道
close(ch)
package main import ( "fmt" ) func main() { //創建一個無緩存的channel ch := make(chan int, 3) //len(ch)緩沖區剩余數據個數, cap(ch)緩沖區大小 fmt.Printf("len(ch) = %d, cap(ch)= %d\n", len(ch), cap(ch)) //新建協程 go func() { for i := 0; i < 10000; i++ { fmt.Printf("子協程:i = %d\n", i) ch <- i //往chan寫內容 //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<- ?表示數據進入管道,只寫
<-chan 表示數據從管道出來,只讀
注意:雙向可轉為單向,單向不可轉為雙向
package main //"fmt" func main() { //創建一個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 }
管道消費者生產者模型
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() { //創建一個雙向通道 ch := make(chan int) //生產者,生產數字,寫入channel //新開一個協程 go producer(ch) //channel傳參,引用傳遞 //消費者,從channel讀取內容,打印 consumer(ch) }
原文鏈接:https://www.cnblogs.com/guyouyin123/p/13986351.html
相關推薦
- 2022-05-21 ASP.NET?MVC中_ViewStart.cshtml作用介紹_基礎應用
- 2022-09-10 nginx?Rewrite重寫地址的實現_nginx
- 2023-02-06 C語言預處理器使用方法講解_C 語言
- 2022-08-14 Redis+Caffeine兩級緩存的實現_Redis
- 2024-07-18 Spring Security之認證過濾器
- 2022-11-08 切換tab時,van-list中的onload事件沒觸發
- 2022-07-12 Linux中xargs命令的用法
- 2022-04-19 C語言進階可變參數列表_C 語言
- 最近更新
-
- 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同步修改后的遠程分支