Go 語言 Goroutines

2023-03-14 16:55 更新

原文鏈接:https://gopl-zh.github.io/ch8/ch8-01.html


8.1. Goroutines

在Go語言中,每一個(gè)并發(fā)的執(zhí)行單元叫作一個(gè)goroutine。設(shè)想這里的一個(gè)程序有兩個(gè)函數(shù),一個(gè)函數(shù)做計(jì)算,另一個(gè)輸出結(jié)果,假設(shè)兩個(gè)函數(shù)沒有相互之間的調(diào)用關(guān)系。一個(gè)線性的程序會(huì)先調(diào)用其中的一個(gè)函數(shù),然后再調(diào)用另一個(gè)。如果程序中包含多個(gè)goroutine,對(duì)兩個(gè)函數(shù)的調(diào)用則可能發(fā)生在同一時(shí)刻。馬上就會(huì)看到這樣的一個(gè)程序。

如果你使用過操作系統(tǒng)或者其它語言提供的線程,那么你可以簡單地把goroutine類比作一個(gè)線程,這樣你就可以寫出一些正確的程序了。goroutine和線程的本質(zhì)區(qū)別會(huì)在9.8節(jié)中講。

當(dāng)一個(gè)程序啟動(dòng)時(shí),其主函數(shù)即在一個(gè)單獨(dú)的goroutine中運(yùn)行,我們叫它main goroutine。新的goroutine會(huì)用go語句來創(chuàng)建。在語法上,go語句是一個(gè)普通的函數(shù)或方法調(diào)用前加上關(guān)鍵字go。go語句會(huì)使其語句中的函數(shù)在一個(gè)新創(chuàng)建的goroutine中運(yùn)行。而go語句本身會(huì)迅速地完成。

f()    // call f(); wait for it to return
go f() // create a new goroutine that calls f(); don't wait

下面的例子,main goroutine將計(jì)算菲波那契數(shù)列的第45個(gè)元素值。由于計(jì)算函數(shù)使用低效的遞歸,所以會(huì)運(yùn)行相當(dāng)長時(shí)間,在此期間我們想讓用戶看到一個(gè)可見的標(biāo)識(shí)來表明程序依然在正常運(yùn)行,所以來做一個(gè)動(dòng)畫的小圖標(biāo):

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)
}

動(dòng)畫顯示了幾秒之后,fib(45)的調(diào)用成功地返回,并且打印結(jié)果:

Fibonacci(45) = 1134903170

然后主函數(shù)返回。主函數(shù)返回時(shí),所有的goroutine都會(huì)被直接打斷,程序退出。除了從主函數(shù)退出或者直接終止程序之外,沒有其它的編程方法能夠讓一個(gè)goroutine來打斷另一個(gè)的執(zhí)行,但是之后可以看到一種方式來實(shí)現(xiàn)這個(gè)目的,通過goroutine之間的通信來讓一個(gè)goroutine請(qǐng)求其它的goroutine,并讓被請(qǐng)求的goroutine自行結(jié)束執(zhí)行。

留意一下這里的兩個(gè)獨(dú)立的單元是如何進(jìn)行組合的,spinning和菲波那契的計(jì)算。分別在獨(dú)立的函數(shù)中,但兩個(gè)函數(shù)會(huì)同時(shí)執(zhí)行。



以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)