中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當前位置: 首頁 > news >正文

編程培訓機構出來的能找到工作嗎抖音seo

編程培訓機構出來的能找到工作嗎,抖音seo,上海建設廳是哪個網(wǎng)站,推廣型網(wǎng)站建設地址使用的go版本為 go1.21.2 首先我們寫一個簡單的panic調度與捕獲代碼 package mainfunc main() {defer func() {recover()}()panic("panic test") }通過go build -gcflags -S main.go獲取到對應的匯編代碼 可以看到當我們調度panic時,Go的編譯器會將這段…

使用的go版本為 go1.21.2

首先我們寫一個簡單的panic調度與捕獲代碼

package mainfunc main() {defer func() {recover()}()panic("panic test")
}

通過go build -gcflags -S main.go獲取到對應的匯編代碼

可以看到當我們調度panic時,Go的編譯器會將這段代碼翻譯為CALL runtime.gopanic(SB)
我們先來看一下panic構造體的底層源碼

panic源碼與解讀

//代碼位置 $GOROOT/src/runtime/runtime2.go L:1035type _panic struct {argp      unsafe.Pointer // 指向在 panic 運行期間執(zhí)行的延遲調用參數(shù)的指針,不可移動 - liblink 工具已知其位置arg       any            // 參數(shù)link      *_panic        // panic鏈表pc        uintptr        // 返回到運行時的位置sp        unsafe.Pointer // 返回到運行時的棧指針位置recovered bool           // 是否已被恢復aborted   bool           // 是否已被中止goexit    bool           // 是否執(zhí)行了 Goexit 函數(shù)
}

gopanic源碼與解讀

//代碼位置 $GOROOT/src/runtime/panic.go L:826
// 實現(xiàn)預聲明函數(shù) panic
func gopanic(e any) {// 處理異常參數(shù)為 nil 的情況if e == nil {// 如果 debug.panicnil 不等于 1,將e設置為PanicNilError類型//if debug.panicnil.Load() != 1 {e = new(PanicNilError)} else {panicnil.IncNonDefault()}}// 獲取當前的Ggp := getg()// 判斷當前M上運行的G是不是當前Gif gp.m.curg != gp {print("panic: ")printany(e)print("\n")throw("panic on system stack")}// malloc過程中出現(xiàn)panicif gp.m.mallocing != 0 {print("panic: ")printany(e)print("\n")throw("panic during malloc")}// 禁止搶占的情況下執(zhí)行 panic (!="" 保持當前G在這M運行)if gp.m.preemptoff != "" {print("panic: ")printany(e)print("\n")print("preempt off reason: ")print(gp.m.preemptoff)print("\n")throw("panic during preemptoff")}//  當初M處于鎖的狀態(tài)if gp.m.locks != 0 {print("panic: ")printany(e)print("\n")throw("panic holding locks")}// 定義一個panic變量var p _panicp.arg = e //這個e 就是我們panic("xxxx") 里面寫的東西//將這個panic加入到G的_panic鏈表中去p.link = gp._panic gp._panic = (*_panic)(noescape(unsafe.Pointer(&p))) // 增加運行panic延遲計數(shù)runningPanicDefers.Add(1)// 計算 getcallerpc/getcallersp,以避免掃描 gopanic 幀addOneOpenDeferFrame(gp, getcallerpc(), unsafe.Pointer(getcallersp()))for {//逐步獲取當前G中的defer調用d := gp._defer// 如果獲取到的構造體為空,直接返回。if d == nil {break}// 如果當前_defer運行,將_defer從G的延遲鏈表移除,釋放對應的_defer構造體資源,防止重復執(zhí)行if d.started {if d._panic != nil {d._panic.aborted = true}d._panic = nilif !d.openDefer {d.fn = nilgp._defer = d.linkfreedefer(d)continue}}// 標記當前_defer為運行狀態(tài)d.started = true// 記錄_defer的panicd._panic = (*_panic)(noescape(unsafe.Pointer(&p)))done := trueif d.openDefer { //如果_defer使用了 open-coded defers(編碼的延遲調用)// 運行open-coded defer函數(shù)done = runOpenDeferFrame(d) //如果當前棧下面沒有其他延遲函數(shù),則返回trueif done && !d._panic.recovered { //panic沒有recoveraddOneOpenDeferFrame(gp, 0, nil)}} else {//執(zhí)行對應方法//getargp返回其caller的保存callee參數(shù)的地址p.argp = unsafe.Pointer(getargp()) d.fn()}p.argp = nilif gp._defer != d {throw("bad defer entry in panic")}d._panic = nilpc := d.pcsp := unsafe.Pointer(d.sp)if done { //將_defer從G的延遲鏈表移除,釋放對應的_defer構造體資源d.fn = nilgp._defer = d.linkfreedefer(d)}if p.recovered { //panic已經恢復gp._panic = p.link if gp._panic != nil && gp._panic.goexit && gp._panic.aborted {// A normal recover would bypass/abort the Goexit.  Instead,// we return to the processing loop of the Goexit.gp.sigcode0 = uintptr(gp._panic.sp)gp.sigcode1 = uintptr(gp._panic.pc)mcall(recovery)throw("bypassed recovery failed") // mcall should not return}runningPanicDefers.Add(-1)// 從G中獲取一個_defer構造體d := gp._defervar prev *_deferif !done { //如果未執(zhí)行完畢,跳過當前的幀直接執(zhí)行下一個prev = dd = d.link}for d != nil {if d.started { //如果啟動退出循環(huán)break}if d.openDefer { //如果使用了 open-coded defersif prev == nil { //將_defer從G的延遲鏈表移除釋放_defergp._defer = d.link} else {prev.link = d.link}newd := d.linkfreedefer(d)d = newd} else {prev = dd = d.link}}gp._panic = p.link //上面有對應的賦值,又重新賦了一遍沒啥用for gp._panic != nil && gp._panic.aborted { //循環(huán)G中的_panic鏈表,去掉已經被標記中止的_panicgp._panic = gp._panic.link}if gp._panic == nil { // 如果當前G沒有panic, 重置信號為0gp.sig = 0}// 將恢復幀發(fā)送給recovery.gp.sigcode0 = uintptr(sp)gp.sigcode1 = pcmcall(recovery)throw("recovery failed") // mcall should not return}}// 沒有更多的延遲調用,現(xiàn)在采用傳統(tǒng)的 panic 方式// 由于在凍結世界之后調用任意用戶代碼是不安全的,// 我們調用 preprintpanics 來調用所有必要的 Error// 和 String 方法,以在 startpanic 之前準備好 panic 字符串。preprintpanics(gp._panic)fatalpanic(gp._panic) //觸發(fā)致命的 panic*(*int)(nil) = 0 //為了消除編譯器的錯誤提示
}

?當我們調度recover時,Go的編譯器會將這段代碼翻譯為CALL runtime.gorecover(SB)

gorecover源碼與解讀

//代碼位置 $GOROOT/src/runtime/panic.go L:1045
func gorecover(argp uintptr) any {gp := getg() //獲取當前Gp := gp._panic // 從當前G中獲取一個_panic// 如果G存在panic,它的狀態(tài)不為中止,還未進行painc捕獲,函數(shù)調用參數(shù)相同if p != nil && !p.goexit && !p.recovered && argp == uintptr(p.argp) {p.recovered = truereturn p.arg}return nil
}

總結

從上面的源碼我們可以了解到panic的大致邏輯,當使用panic關鍵詞時,將painc加入到G的_panic鏈表中去. 調度時 defer func() {recover()}(),會改寫_painc中的recovered字段,可恢復的panic必須要recover的配合。 而且這個recover必須位于同一goroutine的直接調用鏈上,否則無法對 panic 進行恢復,未寫完有些細節(jié)點還是沒讀懂,后續(xù)查閱資料補充。

http://www.risenshineclean.com/news/66314.html

相關文章:

  • 醫(yī)藥招商網(wǎng)站大全襄陽seo優(yōu)化排名
  • 家裝公司報價無錫seo排名收費
  • 肥東縣建設局網(wǎng)站代發(fā)百度關鍵詞排名
  • 網(wǎng)站建設哪家好nuoweb中國去中心化搜索引擎
  • 廈門微網(wǎng)站制作搜索引擎調價工具哪個好
  • wordpress購物網(wǎng)站搜狗輸入法下載安裝
  • wordpress submit 500廣州seo網(wǎng)站營銷
  • 如何建立一個網(wǎng)站要多少錢百度開戶怎么開
  • 龍崗網(wǎng)站制作公司一般多少錢百度官方網(wǎng)站登錄
  • 手機網(wǎng)站建設公司網(wǎng)絡營銷策劃方案案例
  • 個人站長網(wǎng)站應該如何定位網(wǎng)絡推廣怎么收費
  • 上海專業(yè)做網(wǎng)站友情鏈接什么意思
  • 網(wǎng)站建設怎么付費目前搜索引擎排名
  • 一個網(wǎng)站建設都需要什么企業(yè)網(wǎng)站的優(yōu)化建議
  • 做網(wǎng)站開封b站推廣怎么買
  • 客戶網(wǎng)站做供應商自薦有用嗎百度關鍵詞搜索指數(shù)
  • dreamweaver屬于什么軟件seo是什么字
  • 關于網(wǎng)站建設的通知百度網(wǎng)站流量統(tǒng)計
  • 南京佛搜做網(wǎng)站公司互聯(lián)網(wǎng)營銷具體做什么
  • 南京做網(wǎng)站的有哪些apple日本網(wǎng)站
  • 做網(wǎng)站建設最好學什么手機端競價惡意點擊能防止嗎
  • 懷化市建設局網(wǎng)站地址百度網(wǎng)盤客服中心電話
  • 哪個網(wǎng)站可以免費學設計百度平臺商家客服電話
  • 常州外貿網(wǎng)站建設公司網(wǎng)絡科技有限公司
  • 麻栗坡做網(wǎng)站線下實體店如何推廣引流
  • 織夢本地做網(wǎng)站手機網(wǎng)址大全123客戶端下載
  • 網(wǎng)站制作軟件排名上海企業(yè)網(wǎng)站seo
  • 湖南新能源公司中企動力網(wǎng)站建設com天堂網(wǎng)
  • 網(wǎng)站設計公司 上線上免費推廣平臺都有哪些
  • 裝飾公司怎樣做網(wǎng)站重慶seo小潘大神