hello word(協程)的大致執行過程
阿新 • • 發佈:2020-10-22
----------helloword執行流程------==
- hello word 程式被編譯成可執行檔案
載入到記憶體中
- 對於程式執行空間中的程式碼段,
重要的是程式執行入口
,不同平臺執行入口不一樣
- 在進行一系列的程式程式碼檢查和初始化之後會已runtime.main為程式執行入口
建立main goroutine
- main goutine 執行以後才會呼叫我們編寫的main.main
資料段
全域性變數 g0。m0
- 協程對應的資料結構是runtime.g,
工作執行緒對應的是runtime.m
,全域性變數g0就是主協程對應的g,全域性變數m0就是主執行緒對應的m
- 與其他協程不同的是,他的協程棧 是由主執行緒棧上分配的
- G0 持有m0的指標,m0 也記錄著g0的指標,
而且一開始m0上執行的協程正是g0
- 全域性變數allgs記錄著所有的g,allm用於記錄所有的m.全域性變數sched(代表的是排程器,資料結構示runtime.schedt,
記錄所有空閒的m,空閒的p,全域性佇列runq等
)全域性變數allp記錄所有的P
GMP 模型
一開始排程模型只有MG,但是因為頻繁的加鎖和解鎖帶來很大的資源消耗
- 每個M和本地的自己的P繫結,這樣可以避免只有一個p帶來的加鎖和解鎖的效能消耗
- 還有一個全域性佇列P,用於所有的P滿了之後放入全域性P中
- M先從關聯的本地佇列中獲取,如果沒有的話在到全域性佇列領取一些任務,全域性都沒有就會隨機竊取其他P的任務放入本地佇列
p的建立過程
- 全域性變數allp記錄所有的p
- 程式初始化的時候會進行排程器初始化,這時會根據GOMAXPROCS環境變數來建立P的個數,
並將allp[0]和m[0]繫結建立關係
main goroutin建立之前GPM關係
程式初始化
- 佇列裡只有main goutine 切換到main goutine
- 執行入口是runtime.main,會建立監控執行緒,進行包初始化等,然後呼叫main.main,輸出hello word
- 在mian.main返回之後會呼叫exit()退出結束程序
通過協程輸出hello word過程
- 當main.main被執行時就會建立一個新的goroutie
- 會被編譯器轉為newproc函式呼叫,呼叫時,之後給入口和引數,而newproc函式會給goroutine建立一個棧幀,目的是讓協程結束後,返回到goexit中,進行協程資源回收
協程返回以後怎麼樣了
協程返回後怎麼樣了,是被回收了嗎
-
如果只有一個main.goroutine,那麼執行完畢後後呼叫exit函式,釋放空間記憶體,進行資源回收
-
時候time.sleep 會將main.goroutine放入等待佇列,為waiting狀態,其他寫成得以執行,等到sleep執行之後,time會把main goroutine重新置為——Grunnable狀態,放回到runq的佇列中,再然後就結束了,exit呼叫,程序退出,這是隻有一個p的情況
建立多個p的退出
- 預設會加到當前p的本地佇列
- 有空閒p的情況下,就可以啟動新的執行緒關聯這個p,並把hello goroutine 放入到本地佇列中=