1.無緩沖Channel
package main
import (
"fmt"
"time"
)
// 子goroutine,主goroutine結束,子也結束
func NewTask() {
i := 0
for {
i++
fmt.Println("new Goroutine: i =", i)
time.Sleep(1 * time.Second)
}
}
func main() {
//定義一個無緩沖的channel
c := make(chan int)
go func() {
defer fmt.Println("go goroutine 結束")
fmt.Println("go goroutine 正在進行....")
c <- 66 // 將66寫的chan中
}()
// 從channel中讀取資料,復制給num
num := <-c
fmt.Println("num is ", num)
}
// 結果:
go goroutine 正在進行....
go goroutine 結束
num is 66
注意:
- 有沒有可能main方法先執行完,sub go還沒發送給c資訊?
不會,當main從chan中拿不到資料,會阻塞等待
- sub go把66放到chan中,main還沒來得及讀,defer會執行嗎?
不會,因為是無緩沖channel,子sub go會阻塞等待main 獲取資料

2.有緩沖Channel
package main
import (
"fmt"
"time"
)
// 子goroutine,主goroutine結束,子也結束
func NewTask() {
i := 0
for {
i++
fmt.Println("new Goroutine: i =", i)
time.Sleep(1 * time.Second)
}
}
func main() {
//定義一個有緩沖的channel
c := make(chan int, 3)
fmt.Println("c的length =", len(c), "c的cap =", cap(c))
go func() {
defer fmt.Println("go goroutine 結束")
for i := 0; i < 4; i++ {
c <- i // 將i寫的chan中
fmt.Println("go goroutine 正在進行....,發送的元素:", i, "length =", len(c), "cap = ", cap(c))
}
}()
time.Sleep(3 * time.Second)
// 從channel中讀取資料,復制給num
for i := 0; i < 3; i++ {
num := <-c
fmt.Println("num is ", num)
}
fmt.Println("main 結束 ")
}
// 結果:
go goroutine 正在進行....,發送的元素: 0 length = 1 cap = 3
go goroutine 正在進行....,發送的元素: 1 length = 2 cap = 3
go goroutine 正在進行....,發送的元素: 2 length = 3 cap = 3
num is 0
num is 1
num is 2
main 結束
go goroutine 正在進行....,發送的元素: 3 length = 3 cap = 3
go goroutine 結束
注意:
- 當go goroutine中channel的元素滿了,將會被阻塞,直到獲取完一個num即繼續運行
- 當channel為空,從里面取資料也會阻塞

3.關閉channel
- 關閉channel不用像關閉檔案一樣,經常去關閉
- 關閉channel后無法再向channel中發送資料(引發panic error)
- 關閉channel后,可以繼續從channel中獲取資料
- 對于nil channel,一定發送阻塞錯誤,記住一定要make
感覺興趣的小伙伴可以加好友一起交流!!
4.Channel與range的使用
for data := range c {
fmt.Println(data)
}
5.Channel與select的使用
單個流程下go只能監控一個Channel狀態,select可以完成多個Channel監控狀態
package main
import (
"fmt"
)
func feibonicii(c, quit chan int) {
x, y := 1, 1
for {
select {
case c <- x: //如果c可寫,將x寫入c中
x = y
y = x + y
case <-quit: // 如果quit可讀,則sub go已執行完任務
fmt.Println("quit....")
return
}
}
}
func main() {
c := make(chan int)
quit := make(chan int)
// sub go
go func() {
for i := 0; i < 16; i++ {
fmt.Println(<-c)
}
quit <- 0
}()
// main go
feibonicii(c, quit)
}

轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/275847.html
標籤:區塊鏈
