golang channel 管道 有無快取的區別

2021-08-13 01:03:04 字數 2921 閱讀 2498

無緩衝的與有緩衝channel有著重大差別,那就是乙個是同步的 乙個是非同步的。

比如c1:=make(chan int)         無緩衝

c2:=make(chan int,1)      有緩衝

c1<-1                            

無緩衝: 不僅僅是向 c1 通道放 1,而是一直要等有別的攜程 <-c1 接手了這個引數,那麼c1<-1才會繼續下去,要不然就一直阻塞著。

有緩衝: c2<-1 則不會阻塞,因為緩衝大小是1(其實是緩衝大小為0),只有當放第二個值的時候,第乙個還沒被人拿走,這時候才會阻塞。

我對以上做一些解釋,首先確實得承認channel有快取與無快取確實差別巨大,快取為1和不設定快取輸出有差別。但是上面有快取的解釋是合理的,無快取的我保留一下意見,用用**例項來做下分析。

package main  

import (  

"fmt"  

)    

func main()  else   

//          fmt.println("goforend", i)  

}  }()  

for j := 1; j <= 3; j++   

close(jobs)  

fmt.println("sent all jobs")  

<-done  

}

其輸出是:

sent job 1  

received job 1  

sent job 2  

received job 2  

sent job 3  

sent all jobs  

received job 3  

received all jobs

這是有快取的情況,輸出跟大家所預想的是一樣的,每次遇到

jobs <- j
程式會繼續向下執行,直到程式迴圈到下次 jobs <- j,因為jobs的開闢的快取已滿,故程式轉而執行goroutine部分,在goroutine中,當程式執行至

j, more := <-jobs
取出channel中的值,等到goroutine中遇到阻塞,回到外部main()函式繼續執行

jobs := make(chan int, 1)
修改為

jobs := make(chan int)
並將**中的注釋部分全部還原執行。

其輸出是:

outfor 1  

gostart  

goforstart 1  

received job 1  

goforend 1  

goforstart 2  

sent job 1  

outfor 2  

sent job 2  

outfor 3  

received job 2  

goforend 2  

goforstart 3  

received job 3  

goforend 3  

goforstart 4  

sent job 3  

sent all jobs  

received all jobs

我們分析:

當for迴圈執行至第一次 jobs <- j ,程式直接進入goroutine,由輸出的「 gostart」 緊跟 「outfor 1」 得到驗證。然後程式執行至在goroutine中for的第二次迴圈

j, more := <-jobs
處阻塞,回到外部main()的for迴圈。

但外部main的for迴圈執行第二圈時,並未在 jobs <- j  後進入goroutine,而是繼續執行,由

sent job 2  

outfor 3

緊跟

outfor 2
得到驗證。

而外部for進入第三次迴圈時阻塞,因為jobs中得值還未取出,故而轉入goroutine繼續執行。

問題出在

jobs <- j
是繼續執行還是阻塞去在其他goroutine中傳遞值,按照本文開頭索引的帖子所指出,應該jobs 通道放j,需要有攜程接手這個引數,才可繼續執行,但上面得分析看到情況並非如此。

package main  

import (  

"fmt"  

)    

func main()   

}  }()  

for j := 0; j < 5; j++   

close(jobs)  

fmt.println("finish.")  

}

其輸出為:

goroutin start  

get  0  

sent job  0  

sent job  1  

get  1  

get  2  

sent job  2  

sent job  3  

get  3  

get  4  

sent job  4  

finish.

當遇到向channel寫入值,是否往下執行是交替的,也就是說是隨機的。

本文示例環境是go 1.4,本文所做的解釋也是因為攜程都是利用同一cpu在不同時間片上執行所做的輸出分析。

goroutine利用阻塞同步攜程之間的資料是非常重要的思想,但大家程式設計的時候要特別小心。

golang channel基本操作

channel可以實現執行緒的阻塞。建立無緩衝區channel,只能存放乙個值。var ch make chan int 建立有緩衝區channel,可以存放多個值,值到達上限才會阻塞。var ch1 make chan int,3 賦值 ch 555 取值 ch 關閉chnneal,關閉後無法在使...

深入學習golang channel

網路,併發 是go語言的兩大feature。go語言號稱 網際網路的c語言 與使用傳統的c語言相比,寫乙個server所使用的 更少,也更簡單。寫乙個server除了網路,另外就是併發,相對python等其它語言,go對併發支援使得它有更好的效能。goroutine和channel是go在 併發 方...

Golang channel 使用總結(一)

package main import fmt func main hbhly 56 128 demo go run g.go fatal error all goroutines are asleep deadlock goroutine 1 chan send main.main search ...