<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Goroutine 開啟和退出到底做了什么?

          共 2012字,需瀏覽 5分鐘

           ·

          2021-04-18 22:04

          點擊上方藍(lán)色“Go語言中文網(wǎng)”關(guān)注,每天一起學(xué) Go

          Illustration created for “A Journey With Go”, made from the original Go Gopher, created by Renee French.

          ??本文基于 Go 1.14。

          在 Go 中,協(xié)程就是一個包含程序運(yùn)行時的信息的結(jié)構(gòu)體,如棧,程序計數(shù)器,或者它當(dāng)前的 OS 線程。調(diào)度器還必須注意 Goroutine 的開始和退出,這兩個階段需要謹(jǐn)慎管理。

          如果你想了解更多關(guān)于棧和程序計數(shù)器的信息,我推薦你閱讀我的文章 Go:協(xié)程切換時涉及到哪些資源?[1]。

          開啟

          開啟一個協(xié)程的處理過程相當(dāng)簡單。我們用一個程序作為例子:

          main 函數(shù)在打印信息之前開啟了一個協(xié)程。由于協(xié)程會有自己的運(yùn)行時間,因此 Go 通知運(yùn)行時配置一個新協(xié)程,意味著:

          • 創(chuàng)建棧
          • 收集當(dāng)前程序計數(shù)器或調(diào)用方數(shù)據(jù)的信息
          • 更新協(xié)程內(nèi)部數(shù)據(jù),如 ID 或 狀態(tài)

          然而,協(xié)程沒有立即獲取運(yùn)行時狀態(tài)。新創(chuàng)建的協(xié)程被加入到了本地隊列的最前端,會在 Go 調(diào)度的下一周期運(yùn)行。下面是現(xiàn)在這種狀態(tài)的示意圖:

          把協(xié)程放在隊列的前端,這樣它就會在當(dāng)前協(xié)程運(yùn)行之后第一個運(yùn)行。如果有工作竊取發(fā)生,它不是在當(dāng)前線程就是在另一個線程運(yùn)行。

          我推薦你閱讀我的文章 Go: Go 調(diào)度器中的工作竊取[2]來獲取更多信息。

          在匯編指令中也可以看到協(xié)程的創(chuàng)建過程:

          協(xié)程被創(chuàng)建并被加入到本地協(xié)程隊列后,它直接執(zhí)行主函數(shù)的下一個指令。

          退出

          協(xié)程結(jié)束時,為了不浪費(fèi) CPU 資源,Go 必須調(diào)度另一個協(xié)程。這也使協(xié)程可以在以后復(fù)用。

          在我的文章 Go: 協(xié)程怎么復(fù)用?[3]中你可以找到更多信息。

          然而,Go 需要一個能識別到協(xié)程結(jié)束的方法。這個方法是在協(xié)程創(chuàng)建時控制的。創(chuàng)建協(xié)程時,Go 在將程序計數(shù)器設(shè)置為協(xié)程真實調(diào)用的函數(shù)之前,將堆棧設(shè)置為名為 goexit 的函數(shù)。這個技巧可以使協(xié)程在結(jié)束時必須調(diào) goexit 函數(shù)。下面的程序可以使我們理解得更形象:

          根據(jù)輸出信息進(jìn)行堆棧追蹤:

          /path/to/src/main.go:16
          /usr/local/go/src/runtime/asm_amd64.s:1373

          用匯編寫的 asm_amd64 文件包含這個函數(shù):

          之后,Go 切換到 g0 調(diào)度另一個協(xié)程。

          我們也可以調(diào)用 runtime.Goexit() 來手動終止協(xié)程:

          這個函數(shù)首先運(yùn)行 defer 中的函數(shù),然后會運(yùn)行前面在協(xié)程退出時我們看到的那個函數(shù)。


          via: https://medium.com/a-journey-with-go/go-how-does-a-goroutine-start-and-exit-2b3303890452

          作者:Vincent Blanchon[4]譯者:lxbwolf[5]校對:polaris1119[6]

          本文由 GCTT[7] 原創(chuàng)編譯,Go 中文網(wǎng)[8] 榮譽(yù)推出

          參考資料

          [1]

          Go:協(xié)程切換時涉及到哪些資源?: https://medium.com/a-journey-with-go/go-what-does-a-goroutine-switch-actually-involve-394c202dddb7

          [2]

          Go: Go 調(diào)度器中的工作竊取: https://medium.com/a-journey-with-go/go-work-stealing-in-go-scheduler-d439231be64d

          [3]

          Go: 協(xié)程怎么復(fù)用?: https://medium.com/a-journey-with-go/go-how-does-go-recycle-goroutines-f047a79ab352

          [4]

          Vincent Blanchon: https://medium.com/@blanchon.vincent

          [5]

          lxbwolf: https://github.com/lxbwolf

          [6]

          polaris1119: https://github.com/polaris1119

          [7]

          GCTT: https://github.com/studygolang/GCTT

          [8]

          Go 中文網(wǎng): https://studygolang.com/



          推薦閱讀


          福利

          我為大家整理了一份從入門到進(jìn)階的Go學(xué)習(xí)資料禮包,包含學(xué)習(xí)建議:入門看什么,進(jìn)階看什么。關(guān)注公眾號 「polarisxu」,回復(fù) ebook 獲??;還可以回復(fù)「進(jìn)群」,和數(shù)萬 Gopher 交流學(xué)習(xí)。

          瀏覽 19
          點贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  亚洲一线在线观看 | 天天操人人射 | 中国一区二区精品 | 免费转av的网站 免费做爱视频动漫 | Japanese熟女六十路。无限是 |