無緩衝的與有緩衝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 ...