W3Cschool
恭喜您成為首批注冊用戶
獲得88經(jīng)驗值獎勵
原文鏈接:https://gopl-zh.github.io/ch8/ch8-01.html
在Go語言中,每一個并發(fā)的執(zhí)行單元叫作一個goroutine。設想這里的一個程序有兩個函數(shù),一個函數(shù)做計算,另一個輸出結果,假設兩個函數(shù)沒有相互之間的調(diào)用關系。一個線性的程序會先調(diào)用其中的一個函數(shù),然后再調(diào)用另一個。如果程序中包含多個goroutine,對兩個函數(shù)的調(diào)用則可能發(fā)生在同一時刻。馬上就會看到這樣的一個程序。
如果你使用過操作系統(tǒng)或者其它語言提供的線程,那么你可以簡單地把goroutine類比作一個線程,這樣你就可以寫出一些正確的程序了。goroutine和線程的本質(zhì)區(qū)別會在9.8節(jié)中講。
當一個程序啟動時,其主函數(shù)即在一個單獨的goroutine中運行,我們叫它main goroutine。新的goroutine會用go語句來創(chuàng)建。在語法上,go語句是一個普通的函數(shù)或方法調(diào)用前加上關鍵字go。go語句會使其語句中的函數(shù)在一個新創(chuàng)建的goroutine中運行。而go語句本身會迅速地完成。
f() // call f(); wait for it to return
go f() // create a new goroutine that calls f(); don't wait
下面的例子,main goroutine將計算菲波那契數(shù)列的第45個元素值。由于計算函數(shù)使用低效的遞歸,所以會運行相當長時間,在此期間我們想讓用戶看到一個可見的標識來表明程序依然在正常運行,所以來做一個動畫的小圖標:
gopl.io/ch8/spinner
func main() {
go spinner(100 * time.Millisecond)
const n = 45
fibN := fib(n) // slow
fmt.Printf("\rFibonacci(%d) = %d\n", n, fibN)
}
func spinner(delay time.Duration) {
for {
for _, r := range `-\|/` {
fmt.Printf("\r%c", r)
time.Sleep(delay)
}
}
}
func fib(x int) int {
if x < 2 {
return x
}
return fib(x-1) + fib(x-2)
}
動畫顯示了幾秒之后,fib(45)的調(diào)用成功地返回,并且打印結果:
Fibonacci(45) = 1134903170
然后主函數(shù)返回。主函數(shù)返回時,所有的goroutine都會被直接打斷,程序退出。除了從主函數(shù)退出或者直接終止程序之外,沒有其它的編程方法能夠讓一個goroutine來打斷另一個的執(zhí)行,但是之后可以看到一種方式來實現(xiàn)這個目的,通過goroutine之間的通信來讓一個goroutine請求其它的goroutine,并讓被請求的goroutine自行結束執(zhí)行。
留意一下這里的兩個獨立的單元是如何進行組合的,spinning和菲波那契的計算。分別在獨立的函數(shù)中,但兩個函數(shù)會同時執(zhí)行。
![]() | ![]() |
Copyright©2021 w3cschool編程獅|閩ICP備15016281號-3|閩公網(wǎng)安備35020302033924號
違法和不良信息舉報電話:173-0602-2364|舉報郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號
聯(lián)系方式:
更多建議: