Go語(yǔ)言提供了稱為Goroutines的特殊功能。Goroutine是一種函數(shù)或方法,可與程序中存在的任何其他Goroutine一起獨(dú)立且同時(shí)執(zhí)行。換句話說,每個(gè)Go語(yǔ)言中同時(shí)執(zhí)行的活動(dòng)稱為Goroutines,您可以將Goroutine視為輕量級(jí)線程。與線程相比,創(chuàng)建Goroutines的成本非常小。每個(gè)程序至少包含一個(gè)Goroutine,并且該Goroutine被稱為主Goroutine。如果主Goroutine終止,則所有Goroutine在主Goroutine之下運(yùn)行,那么程序中存在的所有g(shù)oroutine也將終止;Goroutine始終在后臺(tái)運(yùn)行。
您只需使用go關(guān)鍵字作為函數(shù)或方法調(diào)用的前綴,即可創(chuàng)建自己的Goroutine,如以下語(yǔ)法所示:
語(yǔ)法:
func name(){ // 語(yǔ)句 } // 在函數(shù)名前面,使用go關(guān)鍵字 go name()
package main import "fmt" func display(str string) { for w := 0; w < 6; w++ { fmt.Println(str) } } func main() { // 調(diào)用Goroutine go display("Welcome") //正常調(diào)用函數(shù) display("(cainiaoplus.com)") }
輸出:
(cainiaoplus.com) (cainiaoplus.com) (cainiaoplus.com) (cainiaoplus.com) (cainiaoplus.com) (cainiaoplus.com)
在上面的示例中,我們僅創(chuàng)建了display()函數(shù),然后以兩種不同的方式調(diào)用此函數(shù),第一種是Goroutine,即go display("Welcome"),另一種是常規(guī)調(diào)用函數(shù),即display("nhooo")
但是您可能發(fā)現(xiàn)問題了,它只顯示調(diào)用普通函數(shù)的結(jié)果,而不顯示Goroutine的結(jié)果,因?yàn)閳?zhí)行新的Goroutine時(shí),Goroutine調(diào)用會(huì)立即返回。它不像普通函數(shù)那樣等待Goroutine完成執(zhí)行,它們總是在Goroutine調(diào)用后一直前進(jìn)到下一行,并忽略Goroutine返回的值。因此,為了正確執(zhí)行Goroutine,我們對(duì)程序進(jìn)行了一些更改,如以下代碼所示:
修改后的Goroutine示例:
package main import ( "fmt" "time" ) func display(str string) { for w := 0; w < 6; w++ { time.Sleep(1 * time.Second) fmt.Println(str) } } func main() { // 調(diào)用Goroutine go display("Welcome") //調(diào)用普通函數(shù) display("nhooo") }
輸出:
Welcome nhooo nhooo Welcome Welcome nhooo nhooo Welcome Welcome nhooo nhooo
我們?cè)诔绦蛑刑砑恿薙leep()方法,它使主Goroutine在新Goroutine執(zhí)行的1秒之間睡眠1秒,在屏幕上顯示歡迎,然后在1秒的主Goroutine重新調(diào)度并執(zhí)行其操作后終止。這個(gè)過程一直持續(xù)到z的值<6,之后主Goroutine終止。在這里,Goroutine和普通函數(shù)同時(shí)工作。
Goroutine比線程開銷小。
Goroutine存儲(chǔ)在堆棧中,并且堆棧的大小可以根據(jù)程序的要求而增大和縮小。但是在線程中,堆棧的大小是固定的。
Goroutine可以使用通道進(jìn)行通信,并且這些通道經(jīng)過特殊設(shè)計(jì),可以防止在使用Goroutines訪問共享內(nèi)存時(shí)出現(xiàn)爭(zhēng)用情況。
假設(shè)一個(gè)程序有一個(gè)線程,并且該線程有許多與之關(guān)聯(lián)的Goroutine。如果由于資源需求,任何Goroutine阻塞了線程,則所有其余Goroutine將分配給新創(chuàng)建的OS線程。所有這些細(xì)節(jié)對(duì)程序員都是隱藏的。
在Go語(yǔ)言中,您還可以為匿名函數(shù)啟動(dòng)Goroutine,換句話說,您可以簡(jiǎn)單地通過使用go關(guān)鍵字作為該函數(shù)的前綴來創(chuàng)建匿名Goroutine,如以下語(yǔ)法所示:
語(yǔ)法:
//匿名函數(shù)調(diào)用 go func (parameter_list){ // 語(yǔ)句 }(arguments)
package main import ( "fmt" "time" ) func main() { fmt.Println("Welcome!! to Main function") //創(chuàng)建匿名Goroutine go func() { fmt.Println("Welcome!! to (cainiaoplus.com)") }() time.Sleep(1 * time.Second) fmt.Println("GoodBye!! to Main function") }
輸出:
Welcome!! to Main function Welcome!! to (cainiaoplus.com) GoodBye!! to Main function