這篇文章跟大家分析一下“go中的Golang協(xié)程怎么分析”。內(nèi)容詳細(xì)易懂,對(duì)“go中的Golang協(xié)程怎么分析”感興趣的朋友可以跟著小編的思路慢慢深入來閱讀一下,希望閱讀后能夠?qū)Υ蠹矣兴鶐椭?。下面跟著小編一起深入學(xué)習(xí)“go中的Golang協(xié)程怎么分析”的知識(shí)吧。
成都做網(wǎng)站、成都網(wǎng)站制作介紹好的網(wǎng)站是理念、設(shè)計(jì)和技術(shù)的結(jié)合。創(chuàng)新互聯(lián)建站擁有的網(wǎng)站設(shè)計(jì)理念、多方位的設(shè)計(jì)風(fēng)格、經(jīng)驗(yàn)豐富的設(shè)計(jì)團(tuán)隊(duì)。提供PC端+手機(jī)端網(wǎng)站建設(shè),用營(yíng)銷思維進(jìn)行網(wǎng)站設(shè)計(jì)、采用先進(jìn)技術(shù)開源代碼、注重用戶體驗(yàn)與SEO基礎(chǔ),將技術(shù)與創(chuàng)意整合到網(wǎng)站之中,以契合客戶的方式做到創(chuàng)意性的視覺化效果。
1. Hello Goroutine
package main
import (
"fmt"
)
func main() {
go sayHello()
}
func sayHello() {
fmt.Println("Hello Goroutine !!!")
}
go語言開啟協(xié)程的關(guān)鍵詞是go,后面接著一個(gè)匿名函數(shù)或者一個(gè)自定義的函數(shù),但是,如果運(yùn)行了上面的代碼,你會(huì)發(fā)現(xiàn)終端并沒有輸出‘Hello Gorounitn !!!’,為什么呢?
上面的代碼并沒有問題,不會(huì)執(zhí)行錯(cuò)誤,之所以不會(huì)輸出是因?yàn)樵趃olang語言中,main函數(shù)也是一個(gè)協(xié)程,而且是主協(xié)程。什么意思呢?就是每當(dāng)你執(zhí)行g(shù)o項(xiàng)目時(shí)(必需有main函數(shù),而且只能有一個(gè)main函數(shù)),會(huì)首先開啟一個(gè)main函數(shù)的主協(xié)程,這個(gè)主協(xié)程的執(zhí)行時(shí)間會(huì)影響到子協(xié)程,子協(xié)程就是go關(guān)鍵詞加函數(shù),如果主協(xié)程先執(zhí)行完畢,那么子協(xié)程就不會(huì)被執(zhí)行,所以 我把代碼改成這樣:
package main
import (
"fmt"
"time"
)
func main() {
go sayHello()
time.Sleep(time.Second)
}
func sayHello() {
fmt.Println("Hello Goroutine !!!")
}
輸出:
Hello Goroutine !!!
sleep 1s,等待子協(xié)程執(zhí)行,所以會(huì)有輸出。
2. WaitGroup
等待子協(xié)程執(zhí)行用睡眠的方式不符合實(shí)際開發(fā),所以sync包下的WaitGroup可以解決這個(gè)問題,代碼:
package main
import (
"fmt"
"sync"
)
func main() {
wg := &sync.WaitGroup{}
wg.Add(2)
go sayHello(wg)
go sayHello2(wg)
wg.Wait()
}
func sayHello(wg *sync.WaitGroup) {
defer wg.Done()
fmt.Println("Hello Goroutine !!!")
}
func sayHello2(wg *sync.WaitGroup) {
defer wg.Done()
fmt.Println("Hello Golang !!!")
}
解釋:在main函數(shù)里聲明一個(gè)wg變量,wg.Add(2)的意思是我這里有兩個(gè)協(xié)程要執(zhí)行,所以傳入2,如果你有n個(gè)協(xié)程呢?那就傳入n,wg.Done()相當(dāng)與wg.Add(-1)就是該子協(xié)程執(zhí)行完畢。wg.Wait()就是告訴主協(xié)程要等待子協(xié)程執(zhí)行完畢才能退出。
3. Channel
channel,又叫管道,在go里面的管道是協(xié)程之間通信的渠道,類似于咱們常用的消息隊(duì)列。
package main
import (
"fmt"
"strconv"
)
func main() {
ch := make(chan string)
for i := 0; i <= 10; i++ {
go demo(ch, "Hello Channel"+strconv.Itoa(i))
}
for d := range ch {
fmt.Println(">>>>>>>>>>>>>>", d)
}
}
func demo(c chan string, data string) {
c <- data
}
簡(jiǎn)單說明一下,這里就是實(shí)例化了一個(gè)string類型的管道,在調(diào)用函數(shù)的時(shí)候會(huì)把管道當(dāng)作參數(shù)傳遞過去,然后在調(diào)用函數(shù)里面我們不輸出結(jié)果,然后把結(jié)果通過管道返還回去,然后再主線程里面我們通過for range循環(huán)依次取出結(jié)果!
但是這個(gè)程序是有bug的,在程序的運(yùn)行的最后會(huì)出現(xiàn)一個(gè)fatal error,提示所有的協(xié)程都進(jìn)入睡眠狀態(tài),死鎖!
go的管道默認(rèn)是阻塞的(假如你不設(shè)置緩存的話),你那邊放一個(gè),我這頭才能取一個(gè),如果你那邊放了東西這邊沒人取,程序就會(huì)一直等下去,死鎖了,同時(shí),如果那邊沒人放東西,你這邊取也取不到,也會(huì)發(fā)生死鎖!
如何解決這個(gè)問題呢?標(biāo)準(zhǔn)的做法是主動(dòng)關(guān)閉管道,或者你知道你應(yīng)該什么時(shí)候關(guān)閉管道, 當(dāng)然你結(jié)束程序管道自然也會(huì)關(guān)掉!針對(duì)上面的演示代碼,可以這樣寫:
var (
i int
)
for d := range ch {
fmt.Println(">>>>>>>>>>>>>>", d)
//
if i >= 10 {
close(ch)
}
i++
}
因?yàn)槲覀兠鞔_知道總共會(huì)輸出11個(gè)結(jié)果,所以這里簡(jiǎn)單做了一個(gè)判斷,大于等于10就關(guān)閉管道退出for循環(huán),就不會(huì)報(bào)錯(cuò)了!雖然不是符合實(shí)際開發(fā)代碼規(guī)范,但是可以使用,能夠解釋原理。
golang是一種編譯語言,可以將代碼編譯為機(jī)器代碼,編譯后的二進(jìn)制文件可以直接部署到目標(biāo)機(jī)器而無需額外的依賴,所以golang的性能優(yōu)于其他的解釋性語言,且可以在golang中使用goroutine來實(shí)現(xiàn)并發(fā)性,它提供了一個(gè)非常優(yōu)雅的goroutine調(diào)度程序系統(tǒng),可以很容易地生成數(shù)百萬個(gè)goroutine。
關(guān)于go中的Golang協(xié)程怎么分析就分享到這里啦,希望上述內(nèi)容能夠讓大家有所提升。如果想要學(xué)習(xí)更多知識(shí),請(qǐng)大家多多留意小編的更新。謝謝大家關(guān)注一下創(chuàng)新互聯(lián)網(wǎng)站!
分享題目:go中的Golang協(xié)程怎么分析
分享地址:http://www.rwnh.cn/article34/pgccse.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供關(guān)鍵詞優(yōu)化、商城網(wǎng)站、網(wǎng)站改版、外貿(mào)網(wǎng)站建設(shè)、靜態(tài)網(wǎng)站、網(wǎng)站建設(shè)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)