管道基本介紹

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
  */

}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章