成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Goroutine 配上 Panic會怎樣?

開發 前端
goroutine 實現了 M:N 的線程模型,是協程的一種實現。golang 內置的調度器,可以讓多核 CPU 中每個 CPU 執行一個協程。

大家好,我是Z哥。

最近用 Golang 進行編碼也有3個月了,說來慚愧,到現在還沒正兒八經深入學習一下 Golang,一直被工作趕著往前在跑。

最近正好在工作中遇到一個問題,需要對 Golang 中的 goroutine 和 panic & recover 稍做深入的了解,算是忙里偷閑學習一下。

對 goroutine 的底層細節就不展開了,網上有不少相關的文章解讀,如果你愿意的話,也可以去扒一下 Golang 的源碼。

簡單對 goroutine 進行一下概括就是:

goroutine 實現了 M:N 的線程模型,是協程的一種實現。golang 內置的調度器,可以讓多核 CPU 中每個 CPU 執行一個協程。

單從表現來看,你可以將 goroutine 看作是 java 之類編程語言中的多線程的運行效果。

好了,那么問題來了:goroutine 中發生 panic 會怎樣?

話不多說,實踐是檢驗真理的唯一標準,我們直接上手 coding。

func main()  {
go panicInGoroutine()

//以下3行代碼是為了讓控制臺掛起,等待gorouine運行完畢。
fmt.Println("wait")
input := bufio.NewScanner(os.Stdin)
input.Scan()
}

func panicInGoroutine() {
panic("panic in goroutine.")
}

運行代碼的結果如下:

可以看到,整個程序都崩了。

那么,如果在 goroutine 里的 goroutine 發出 panic 呢?也是一樣的效果,程序崩了。

可能你會覺得整個程序之所以會崩,是因為異常被層層上拋到主線程導致的,其實并非如此。在 Golang 中,任何地方發生的任意一個 panic,都會直接程序退出。

那么怎么才能讓程序不退出呢?

通過調用 recover() 方法來捕獲 panic 并恢復將要崩掉的程序。

func main() {
go panicInGoroutine()

//以下3行代碼是為了讓控制臺掛起,等待gorouine運行完畢。
fmt.Println("wait")
input := bufio.NewScanner(os.Stdin)
input.Scan()
}

func panicInGoroutine() {
//recover()必須要和defer配合一起用,確保一旦執行到該方法體,這里定義的defer方法一定會被執行,哪怕是發生了panic。
defer func() {
err := recover()
if err != nil {
fmt.Printf("recover receive a err: %+v \n", err)
}
}()

panic("panic in goroutine.")
}

執行上面的代碼,結果如下:

可以看到,程序沒有再崩了。那么新的問題又來了,能不能把 recover() 放到最外層的方法里,這樣可以更好地實現一次 recover() 覆蓋當前方法其下所有的 panic。

func main() {
defer func() {
err := recover()
if err != nil {
fmt.Printf("recover receive a err: %+v \n", err)
}
}()

go panicInGoroutine()

//以下3行代碼是為了讓控制臺掛起,等待gorouine運行完畢。
fmt.Println("wait")
input := bufio.NewScanner(os.Stdin)
input.Scan()
}

func panicInGoroutine() {
panic("panic in goroutine.")
}

運行之后的結果:

竟然還是崩了。如果你是一位 Java 或者 .Net 的程序員習慣了 try-catch-finally 的運行效果肯定對這個結果比較意外。在父方法定義的 recover() 竟然無法捕獲到子方法里的 panic。

其實這里的原因是,外層方法中定義的 recover() 無法捕獲通過 goroutine 執行的子方法中拋出的 panic。在上面的代碼中,我們把 go panicInGoroutine() 前面的 go 去掉就可以正常捕獲了。

好了,那么根據以上這些信息得到的處理 panic 的正確姿勢是什么呢?

  • 必須通過 defer 關鍵字來調用 recover()。
  • 當通過 goroutine 調用某個方法,一定要確保內部有 recover() 機制。

如果你想進一步深入了解 panic 和 recove r的機制,分享你一個超棒的硬核視頻:https://www.bilibili.com/video/BV155411Y7XT,第一遍看可能會有點暈,建議反復看,直到完全理解其原理。


責任編輯:武曉燕 來源: 跨界架構師
相關推薦

2021-09-09 09:46:25

Goroutine 函數runtime

2024-01-31 12:34:16

panic錯誤檢測recover

2013-08-20 09:48:59

2014-12-31 10:02:14

Android可穿戴設備世界

2015-01-05 10:26:14

Android手機廠商

2010-08-20 13:53:20

2015-11-19 14:47:33

富蘭克林編程

2016-10-21 09:45:20

RustFedoraJava

2022-02-22 11:41:06

數據泄露勒索軟件

2021-03-12 08:53:09

GC調度Goroutine

2021-10-29 19:00:30

監控系統數據庫

2014-02-19 16:26:26

VDI部署

2013-03-08 10:07:20

GO語言Goroutine

2023-11-20 22:55:00

Goroutine調度器

2025-03-31 08:57:25

Go程序性能

2014-10-22 10:15:21

賽門鐵克拆分安全公司

2022-11-24 11:09:03

自然語言處理(智能語音

2009-12-03 13:32:04

Virtuozzo捆綁

2015-06-30 15:18:04

2013-07-29 17:04:18

點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 91新视频| 一区中文字幕 | 亚洲成人免费 | 91在线精品秘密一区二区 | 久久伦理电影 | 国产日韩精品在线 | 国产精品精品视频一区二区三区 | 亚洲综合色丁香婷婷六月图片 | 一区二区三区不卡视频 | 国产成人99久久亚洲综合精品 | 亚洲国产高清在线观看 | 狠狠干在线| 久久久久国产一级毛片高清网站 | 狠狠爱视频 | 91免费观看在线 | 日操操 | 国产精品久久精品 | 久久大| 日本特黄a级高清免费大片 国产精品久久性 | 欧美精品a∨在线观看不卡 国产精品久久国产精品 | 狠狠综合久久av一区二区老牛 | 欧美一级片黄色 | 日韩在线免费播放 | 日本欧美在线观看视频 | 欧美日韩高清在线观看 | 亚洲午夜电影 | 欧美男男videos | 国产免费拔擦拔擦8x高清 | 久久久久国产一区二区三区四区 | www久久爱 | 中文天堂网| 99精品福利视频 | 亚洲视频一区二区三区四区 | 91麻豆精品国产91久久久久久 | 夜夜爽99久久国产综合精品女不卡 | 涩涩导航| 中文字幕在线一区 | 91视频在线 | 国产日韩欧美在线播放 | 久久宗合色| 国产丝袜一区二区三区免费视频 |