package main
import “fmt”
/*
爲什麼需要channel
前面使用全局變量加鎖同步來解決goroutine的通訊,但不完美
1)主線程在等待所有goroutine全部完成的時間很難確定,我們這裏設置10秒,僅僅是估算。
2)如果主線程休眠時間長了,會加長等待時間,如果等待時間短了,可能還有goroutine處於工作狀態,這時也會隨主線程的退出而銷燬
3)通過全局變量加鎖同步來實現通信,也並不利用多個協程對全局變量的讀寫操作,
4)上面種種分析都在呼喚一個新的通訊機制-channel
1)channle本質就是一個數據結構-隊列[示意圖]
2)數據是先進先出[FiFO]:first in first out]
3)線程安全,多goroutine訪問時,不需要加鎖,就是說channel本身就是線程安全的(不會發生資源競爭問題)
4)channel是有類型的,一個string的channel只能存放string類型數據。
*/
//var 變量名 chan數據類型
//舉例:
//var intChan chan int(intChan用於存放int數據)
//var mapChan chan map[int]string(mapChan用於存放map[int]string類型]
//var perChan chan Person
//var perChan2 chan Person
//…
/
說明
1)channel是引用類型
2)channel必須初始化才能寫入數據,即make後才能使用
3)管道是由類型的,intChan智能寫入整數int
管道初始化
channel初始化
說明:使用make進行初始化
var intChan chan int
intChan = make(chan int,10)
說明+示意圖
向channel中寫入(存放)數據
var intChan chan int
intChan = make(chan int,10)
num:=999
intChan<-10
intChan<-num
*/
func main(){
//演示一下管道的使用
//1創建一個可以存放3個int類型的管道
var intChan chan int
intChan = make(chan int,3)//管道初始化
//2,看看intChan是什麼
fmt.Printf("intChan的值=%v intChan本身的地址=%p\n",intChan,&intChan)
//3.向管道寫入數據
intChan<-10
num:=211
intChan<-num
//注意點,當我們給管寫入數據時,不能超過其容量
intChan<-50
//如果從channel取出數據後,可以繼續放入
<-intChan
intChan<-98//會報錯超出了,長度變成4,容量變成4,設置3,注意,當寫入數據時,不能超過其容量
//4.看看管道的長度和cap(容量)
fmt.Printf("channel len=%v cap=%v\n",len(intChan),cap(intChan))//2,3
//5.從管道讀取數據
var num2 int
num2 =<-intChan
fmt.Println("num2=",num2)
fmt.Printf("channel len=%v cap=%v\n",len(intChan),cap(intChan))//2,3
//6.在沒有使用協程的情況下,如果我們的管道數據已經全部取出,在取就會報告deadlock
num3 := <-intChan
num4 := <-intChan
//如果從channel取出數據後,可以繼續放入
num5 := <-intChan
fmt.Println("num3=",num3,"num4=",num4,"num5=",num5)
/*
channel使用的注意事項
1)channel中只能存放指定的數據類型
2)channle的數據放滿後,就不能在放入了
3)如果從channel去除數據後,可以繼續放入
4)在沒有使用協程的情況下,如果channel數據取完了,在取,就會報deadlock
*/
}