中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

go中的Golang協程怎么分析

發布時間:2022-01-17 16:06:26 來源:億速云 閱讀:253 作者:kk 欄目:大數據

這篇文章跟大家分析一下“go中的Golang協程怎么分析”。內容詳細易懂,對“go中的Golang協程怎么分析”感興趣的朋友可以跟著小編的思路慢慢深入來閱讀一下,希望閱讀后能夠對大家有所幫助。下面跟著小編一起深入學習“go中的Golang協程怎么分析”的知識吧。

1. Hello Goroutine

    

package main
import (
   "fmt"
)


func main() {

go sayHello()

}

func sayHello() {
  fmt.Println("Hello Goroutine !!!")
}

    

    go語言開啟協程的關鍵詞是go,后面接著一個匿名函數或者一個自定義的函數,但是,如果運行了上面的代碼,你會發現終端并沒有輸出‘Hello Gorounitn !!!’,為什么呢?

    上面的代碼并沒有問題,不會執行錯誤,之所以不會輸出是因為在golang語言中,main函數也是一個協程,而且是主協程。什么意思呢?就是每當你執行go項目時(必需有main函數,而且只能有一個main函數),會首先開啟一個main函數的主協程,這個主協程的執行時間會影響到子協程,子協程就是go關鍵詞加函數,如果主協程先執行完畢,那么子協程就不會被執行,所以 我把代碼改成這樣:

package main
import (
  "fmt"
  "time"
)

func main() {
  go sayHello()
  time.Sleep(time.Second)
}

func sayHello() {
  fmt.Println("Hello Goroutine !!!")
}

輸出:

Hello Goroutine !!!

sleep 1s,等待子協程執行,所以會有輸出。

2. WaitGroup

    等待子協程執行用睡眠的方式不符合實際開發,所以sync包下的WaitGroup可以解決這個問題,代碼:

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函數里聲明一個wg變量,wg.Add(2)的意思是我這里有兩個協程要執行,所以傳入2,如果你有n個協程呢?那就傳入n,wg.Done()相當與wg.Add(-1)就是該子協程執行完畢。wg.Wait()就是告訴主協程要等待子協程執行完畢才能退出。

3. Channel

    channel,又叫管道,在go里面的管道是協程之間通信的渠道,類似于咱們常用的消息隊列。

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
}

    簡單說明一下,這里就是實例化了一個string類型的管道,在調用函數的時候會把管道當作參數傳遞過去,然后在調用函數里面我們不輸出結果,然后把結果通過管道返還回去,然后再主線程里面我們通過for range循環依次取出結果!

    但是這個程序是有bug的,在程序的運行的最后會出現一個fatal error,提示所有的協程都進入睡眠狀態,死鎖!

       go的管道默認是阻塞的(假如你不設置緩存的話),你那邊放一個,我這頭才能取一個,如果你那邊放了東西這邊沒人取,程序就會一直等下去,死鎖了,同時,如果那邊沒人放東西,你這邊取也取不到,也會發生死鎖!

    如何解決這個問題呢?標準的做法是主動關閉管道,或者你知道你應該什么時候關閉管道, 當然你結束程序管道自然也會關掉!針對上面的演示代碼,可以這樣寫:

var (
  i int
)
for d := range ch {
  fmt.Println(">>>>>>>>>>>>>>", d)
  //
  if i >= 10 {
     close(ch)
  }
  i++
}

因為我們明確知道總共會輸出11個結果,所以這里簡單做了一個判斷,大于等于10就關閉管道退出for循環,就不會報錯了!雖然不是符合實際開發代碼規范,但是可以使用,能夠解釋原理。

go是什么

golang是一種編譯語言,可以將代碼編譯為機器代碼,編譯后的二進制文件可以直接部署到目標機器而無需額外的依賴,所以golang的性能優于其他的解釋性語言,且可以在golang中使用goroutine來實現并發性,它提供了一個非常優雅的goroutine調度程序系統,可以很容易地生成數百萬個goroutine。

關于go中的Golang協程怎么分析就分享到這里啦,希望上述內容能夠讓大家有所提升。如果想要學習更多知識,請大家多多留意小編的更新。謝謝大家關注一下億速云網站!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

综艺| 屏东县| 西安市| 临泽县| 三明市| 荔浦县| 眉山市| 曲靖市| 临汾市| 广西| 怀化市| 象州县| 广平县| 惠水县| 湘阴县| 河津市| 英德市| 寿阳县| 兴业县| 博乐市| 海南省| 四平市| 沐川县| 噶尔县| 三河市| 凤阳县| 余干县| 岳阳县| 兴义市| 桑日县| 贵德县| 马公市| 富源县| 永兴县| 湘潭县| 兴山县| 江川县| 龙口市| 无锡市| 前郭尔| 贡觉县|