Go 併發

Go 併發

  • 併發指的是同時處理多個任務的能力。
  • 並行指的是並行處理多個任務的能力。

並行不必定加快運行速度,由於並行組件之間可能須要互相通訊。併發

Go中使用協程,信道來處理併發。函數

協程

Go中主要經過協程實現併發。線程

協程是與其餘函數或方法一塊兒併發運行的函數或方法,協程能夠看做是輕量級線程,可是建立成本更小,咱們常常會看見數以千計的協程併發運行。code

協程相比線程的優點

  • Go協程建立成本低,堆棧大小隻要幾K,並能夠根據應用須要進行遞減,線程必須指定堆棧大小,堆棧是固定不變的。
  • Go中多個協程會複用數量更少的OS線程,就是可能數千個協程公用一個線程。若是線程中一個協程阻塞,OS會再建立一個線程,並把其餘的協程複製到新的線程上。
  • Go經過Channel來進行協程間通訊,Channel防止多個協程訪問共享內存時發生競態條件,信道是Go協程間通訊的管道。

建立協程

調用函數或者方法時,在前面加上關鍵字go能夠運行在新協程上。協程

func hello(){
}

func main(){
	go hello()
}

Main函數運行在主協程上,hello併發的運行在新協程上。隊列

咱們啓動一個新協程,這個新協程會當即返回,而不會等到函數或方法執行完畢。 若是主協程終止,其餘協程也會終止。內存

咱們能夠在主協程中使用休眠阻塞主協程,等待協程執行完畢。ci

信道(Channel)

信道是協程間通訊的管道。同步

每一個信道都關聯一個類型,信道只能運輸這種類型的數據,傳輸其餘類型數據是違法的。it

chan T 表示T傳輸類型的信道

可使用make來定義信道。

a := make(chan int)

經過信道進行發送和接收數據

data : = < - a //讀取信道
a <- data // 寫入信道

經過信道旁邊的箭頭指定是發送數據仍是接收數據。

信道的發送和接收默認是阻塞的

當把數據發送到信道時,發送數據語句發生阻塞直到其餘Go協程從信道讀取到數據纔會解除阻塞。

一樣,當讀取信道數據時,若是沒有其餘協程把數據寫入信道,讀取過程會一直阻塞。

Go協程和信道特性沒有像其餘語言須要加鎖和同步的開銷。

func hello(done chan bool){
	done < - true // 向信道中寫入數據
}

func main(){
	done := make(chan bool)
	go hello(done)
	< - done // 接收數據,會發生阻塞
}

接收多個信道值:

s, c := <-sq, <-cu

死鎖

信道使用過程當中須要考慮的重點是死鎖,當協程給一個信道發送數據時,按理說其餘協程會來接收數據,若是沒有的話,會造成死鎖。 一樣等的從信道讀取數據是,也會產生死鎖。

單向信道

上面的都是雙向信道,即經過信道既能發送數據也能接受數據,咱們也能夠建立單向信道,只能發送或者接受數據。

sendch := make(chan<-int) // 建立了只能發送數據的單項信道

當咱們嘗試今後信道讀取數據時,會報錯。

Go中能夠把雙向信道轉換成單向信道這樣單向信道能正常讀寫,可是不能把單向信道轉成雙向信道。

關閉信道和遍歷信道

數據發送方能夠關閉信道,通知接收方這個信道再也不產生新數據。

檢查信道是否關閉:

v, ok := <- ch // 接收數據,同時用另外一個變量檢查關閉狀態

若是ok爲false,說明通道關閉,獲得的值爲零值。

func producer(chnl chan int){
	for I := 0; I < 10; I++{
		chill <- I // 循環0~9寫入信道
	}
	close(chnl) // 關閉信道 
}

func main(){
	ch := make(chan int)
	go producer(ch)
	for{ // 主函數死循環
		v, ok := <-ch
		if ok == false{ // 檢查到信道關閉
			break
		}
	}
}

緩衝信道

上面的都是無緩衝信道,接收和發送數據過程都是阻塞的。

緩衝信道,只有在緩衝滿的狀況下才會阻塞緩衝信道發送。只有在緩衝爲空的時候,纔會阻塞信道獲取。

經過make函數傳遞一個容量參數,表明緩衝大小,能夠建立緩衝信道。

ch := make(chan type, capacity)

capacity容量應該大於0,無緩衝信道默認容量爲0。

一樣當緩衝信道堵塞到最大容量時也會產生死鎖。

信道長度和容量

容量表明信道能夠存儲的值數量,使用make函數建立緩衝信道時候會指定容量大小。

緩衝信道長度指的是信道中當前隊列元素個數。

相關文章
相關標籤/搜索