3 回答

TA貢獻1872條經驗 獲得超4個贊
請記住,通道會阻塞,因此 select 語句如下:
select {
case c <- x: // if I can send to c
// update my variables
x, y = y, x+y
case <-quit: // If I can receive from quit then I'm supposed to exit
fmt.Println("quit")
return
}
沒有default案例意味著“如果我不能發送到 c 并且我不能從退出中讀取,直到我可以為止?!?/p>
然后在你的主進程中,你分離出另一個讀取c結果的函數
for i:=0; i<10; i++ {
fmt.Println(<-c) // read in from c
}
quit <- 0 // send to quit to kill the main process.
這里的關鍵是要記住通道會阻塞,并且您正在使用兩個無緩沖通道。使用go分拆第二個功能可以讓您消費,c所以fibonacci將繼續。
Goroutines 是所謂的“綠色線程”。使用關鍵字啟動函數調用go會將其分拆為一個獨立于主執行線運行的新進程。從本質上說,main()和go func() ...同時運行!這很重要,因為我們在此代碼中使用了生產者/消費者模式。
fibonacci產生值并將它們發送到c,從 main 產生的匿名 goroutine 消耗來自的值c并處理它們(在這種情況下,“處理它們”只是意味著打印到屏幕上)。我們不能簡單地產生所有的值然后消費它們,因為c會阻塞。此外fibonacci將永遠產生更多的值(或直到整數溢出),因此即使您有一個具有無限長緩沖區的魔術通道,它也永遠不會到達消費者。

TA貢獻1865條經驗 獲得超7個贊
理解這個代碼示例有兩個關鍵點:
首先,讓我們回顧一下無緩沖通道的工作原理。從文檔
如果通道未緩沖,則發送方會阻塞,直到接收方收到該值。
請注意,在代碼示例兩個通道,c
并且quit
是無緩沖。
其次,當我們使用go
關鍵字啟動一個新的 goroutine 時,執行將與其他例程并行發生。因此,在本例中,我們同時運行兩個走程序:常規的啟動func main()
,并開始了例行go func()...
內func main()
。
我在這里添加了一些內聯注釋,這應該會使事情更清楚: package main import "fmt"
func fibonacci(c, quit chan int) {
x, y := 0, 1
for { // this is equivalent to a while loop, without a stop condition
select {
case c <- x: // when we can send to channel c, and because c is unbuffered, we can only send to channel c when someone tries to receive from it
x, y = y, x+y
case <-quit: // when we can receive from channel quit, and because quit is unbuffered, we can only receive from channel quit when someone tries to send to it
fmt.Println("quit")
return
}
}
}
func main() {
c := make(chan int)
quit := make(chan int)
go func() { // this runs in another goroutine, separate from the main goroutine
for i := 0; i < 10; i++ {
fmt.Println(<-c)
}
quit <- 0
}()
fibonacci(c, quit) // this doesn't start with the go keyword, so it will run on the go routine started by func main()
}

TA貢獻1811條經驗 獲得超6個贊
你已經明白了。
在 go func() 中,我們顯然是從 c 打印值,但是 c 中不應該有任何內容嗎?我能想到的唯一解釋是 go func() 在調用 fibonacci() 之后以某種方式執行。我猜這是一個 goroutine
是的, go 關鍵字啟動了一個 goroutine,所以func()將與fibonacci(c, quit) 同時運行。從 Println 中的通道接收只是阻塞,直到有東西要接收
- 3 回答
- 0 關注
- 195 瀏覽
添加回答
舉報