程序運行后,雖然mian函數(shù)和ready函數(shù)中都print了開始執(zhí)行的語句,但是很明顯,在Goroutine內(nèi)的函數(shù)并沒有執(zhí)行完成。所以我們?yōu)榱烁珳实目刂艷oroutine的并發(fā),需要使用Channel進行控制。
基本概念
Goroutine是一個被Go運行時管理的輕量級線程(A goroutine is a lightweight thread managed by the Go runtime)。
為什么沒有采用現(xiàn)有的表示并發(fā)名詞來解釋Go語言中的并發(fā)呢?因為現(xiàn)有的線程、協(xié)程、進程等都無法準確表達Goroutine。
Goroutines使用方法
函數(shù)并發(fā)執(zhí)行
與普通函數(shù)類似,我們調(diào)用Goroutines時只需要在函數(shù)前加上go關(guān)鍵字。下面的例子中g(shù)o ready()就會并發(fā)執(zhí)行。
package main
import (
"fmt"
"time"
)
func ready() {
fmt.Println("Run func in a goroutine")
}
func main() {
go ready()
time.Sleep(time.Second * 3)
fmt.Println("Main function done")
}
匿名并發(fā)函數(shù)
如果你不想單獨定義,則可以使用匿名方式
package main
import (
"fmt"
"time"
)
func main() {
go func() {
fmt.Println("Run anonymous func in goroutine.")
}()
time.Sleep(time.Second * 3)
fmt.Println("Main function done")
}
如何控制并發(fā)
上面的示例中,我們在主函數(shù)刻意的等待了3秒,如果沒有這3秒會發(fā)生什么呢?我們將time.Sleep注釋掉,另外由于time模塊沒有使用,也需要注釋掉
package main
import (
"fmt"
//"time"
)
func ready() {
fmt.Println("Run func in a goroutine")
}
func main() {
go ready()
//time.Sleep(time.Second * 3)
fmt.Println("Main function done")
}
此時我們發(fā)現(xiàn)Goroutine好像并沒有執(zhí)行,因為只有main函數(shù)中print語句輸出了結(jié)果:
那么究竟Goroutine到底有沒有被觸發(fā)呢?我們再通過這個例子看一下,這個例子中,main函數(shù)需要等待2秒,而Goroutine內(nèi)執(zhí)行的函數(shù)則需要等待5秒
package main
import (
"fmt"
"time"
)
func ready(s int) {
fmt.Printf("Run func in a goroutine and wait for %v\n", s)
time.Sleep(time.Second * time.Duration(s))
fmt.Printf("Run func in a goroutine and wait for %v end\n", s)
}
func main() {
mainWaitSec := 2
go ready(5)
fmt.Printf("Run Main function and wait for %v\n", mainWaitSec)
time.Sleep(time.Second * time.Duration(mainWaitSec))
fmt.Printf("Run Main function and wait for %v done\n", mainWaitSec)
}
程序運行后,雖然mian函數(shù)和ready函數(shù)中都print了開始執(zhí)行的語句,但是很明顯,在Goroutine內(nèi)的函數(shù)并沒有執(zhí)行完成。所以我們?yōu)榱烁珳实目刂艷oroutine的并發(fā),需要使用Channel進行控制。
Run Main function and wait for 2
Run func in a goroutine and wait for 5
Run Main function and wait for 2 done