日韩成人免费在线_国产成人一二_精品国产免费人成电影在线观..._日本一区二区三区久久久久久久久不

當前位置:首頁 > 科技  > 軟件

常見的 Goroutine 泄露,你應該避免

來源: 責編: 時間:2023-10-29 21:44:59 259觀看
導讀Go 語言編寫代碼的最大優點之一是能夠在輕量級線程,即 Goroutines 中并發運行你的代碼。然而,擁有強大的能力也伴隨著巨大的責任。盡管 Goroutines 非常方便,但如果不小心處理,它們很容易引入難以追蹤的錯誤。Goroutine

Go 語言編寫代碼的最大優點之一是能夠在輕量級線程,即 Goroutines 中并發運行你的代碼。vq428資訊網——每日最新資訊28at.com

然而,擁有強大的能力也伴隨著巨大的責任。vq428資訊網——每日最新資訊28at.com

盡管 Goroutines 非常方便,但如果不小心處理,它們很容易引入難以追蹤的錯誤。vq428資訊網——每日最新資訊28at.com

Goroutine 泄露就是其中之一。它在背景中悄悄增長,可能最終在你不知情的情況下使你的應用程序崩潰。vq428資訊網——每日最新資訊28at.com

因此,本文主要介紹 Goroutine 泄露是什么,以及你如何防止泄露發生。vq428資訊網——每日最新資訊28at.com

我們來看看吧!vq428資訊網——每日最新資訊28at.com

vq428資訊網——每日最新資訊28at.com

什么是 Goroutine 泄露?

當創建一個新的 Goroutine 時,計算機在堆中分配內存,并在執行完成后釋放它們。vq428資訊網——每日最新資訊28at.com

Goroutine 泄露是一種內存泄露,當 Goroutine 沒有終止并在應用程序的生命周期中被留在后臺時就會發生。vq428資訊網——每日最新資訊28at.com

讓我們來看一個簡單的例子。vq428資訊網——每日最新資訊28at.com

func goroutineLeak(ch chan int) {    data := <- ch    fmt.Println(data)}func handler() {    ch := make(chan int)        go goroutineLeak(ch)    return}

隨著處理器的返回,Goroutine 繼續在后臺活動,阻塞并等待數據通過通道發送 —— 這永遠不會發生。vq428資訊網——每日最新資訊28at.com

因此,產生了一個 Goroutine 泄露。vq428資訊網——每日最新資訊28at.com

在本文中,我將引導你了解兩種常見的模式,這些模式很容易導致 Goroutine 泄漏:vq428資訊網——每日最新資訊28at.com

  • 遺忘的發送者
  • 被遺棄的接收者

讓我們深入研究!vq428資訊網——每日最新資訊28at.com

遺忘的發送者

遺忘的發送者發生在發送者被阻塞,因為沒有接收者在通道的另一側等待接收數據的情況。vq428資訊網——每日最新資訊28at.com

func forgottenSender(ch chan int) {    data := 3      // This is blocked as no one is receiving the data    ch <- data}func handler () {    ch := make(chan int)      go forgottenSender(ch)    return}

雖然它起初看起來很簡單,但在以下兩種情境中很容易被忽視。vq428資訊網——每日最新資訊28at.com

不當使用 Context

func forgottenSender(ch chan int) {    data := networkCall()      ch <- data}func handler() error {    ctx, cancel := context.WithTimeout(context.Background(), 10*time.Millisecond)    defer cancel()      ch := make(chan int)    go forgottenSender(ch)      select {        case data := <- ch: {            fmt.Printf("Received data! %s", data)                  return nil        }            case <- ctx.Done(): {            return errors.New("Timeout! Process cancelled. Returning")        }    }}

在上面的例子中,我們模擬了一個標準的網絡服務處理程序。vq428資訊網——每日最新資訊28at.com

我們定義了一個上下文,它在10ms后發出超時,隨后是一個異步進行網絡調用的Goroutine。vq428資訊網——每日最新資訊28at.com

select語句等待多個通道操作。它會阻塞,直到其其中一個情況可以運行并執行該情況。vq428資訊網——每日最新資訊28at.com

如果網絡調用完成之前超時到達,case <- ctx.Done() 將會執行,處理程序將返回一個錯誤。vq428資訊網——每日最新資訊28at.com

當處理程序返回時,不再有任何接收者等待接收數據。forgottenSender將被阻塞,等待有人接收數據,但這永遠不會發生!vq428資訊網——每日最新資訊28at.com

這就是Goroutine泄露的地方。vq428資訊網——每日最新資訊28at.com

錯誤檢查后的接收者位置

這是另一個典型的情況。vq428資訊網——每日最新資訊28at.com

func forgottenSender(ch chan int) {    data := networkCall()      ch <- data}func handler() error {    ch := make(chan int)    go forgottenSender(ch)      err := continueToValidateOtherData()    if err != nil {        return errors.New("Data is invalid! Returning.")    }      data := <- ch      return nil}

在上面的例子中,我們定義了一個處理程序并生成一個新的Goroutine來異步進行網絡調用。vq428資訊網——每日最新資訊28at.com

在等待調用返回的過程中,我們繼續其他的驗證邏輯。vq428資訊網——每日最新資訊28at.com

如你所見,當continueToValidateOtherData返回一個錯誤導致處理程序返回時,泄露就發生了。vq428資訊網——每日最新資訊28at.com

沒有人等待接收數據,forgottenSender將永遠被阻塞!vq428資訊網——每日最新資訊28at.com

解決方案:忘記的發送者

使用一個緩沖通道。vq428資訊網——每日最新資訊28at.com

如果你回想一下,忘記的發送者發生是因為另一端沒有接收者。阻塞問題的罪魁禍首是一個無緩沖的通道!vq428資訊網——每日最新資訊28at.com

一個無緩沖的通道是在消息發出時立即需要一個接收者的,否則發送者會被阻塞。它是在沒有為通道分配容量的情況下聲明的。vq428資訊網——每日最新資訊28at.com

func forgottenSender(ch chan int) {    data := 3      // This will NOT block    ch <- data}func handler() {    // Declare a BUFFERED channel    ch := make(chan int, 1)      go forgottenSender(ch)    return}

通過為通道添加特定的容量,在這種情況下為1,我們可以減少所有提到的問題。vq428資訊網——每日最新資訊28at.com

發送者可以在不需要接收者的情況下將數據注入通道。vq428資訊網——每日最新資訊28at.com

被遺棄的接收者

正如其名字所暗示的,被遺棄的接收者是完全相反的情況。vq428資訊網——每日最新資訊28at.com

當一個接收者被阻塞,因為另一邊沒有發送者發送數據時,它就會發生。vq428資訊網——每日最新資訊28at.com

func abandonedReceiver(ch chan int) {    // This will be blocked    data := <- ch      fmt.Println(data) }func handler() {    ch := make(chan int)      go abandonedReceiver(ch)      return}

第3行一直被阻塞,因為沒有發送者發送數據。vq428資訊網——每日最新資訊28at.com

讓我們再次了解兩個常見的場景,這些場景經常被忽視。vq428資訊網——每日最新資訊28at.com

發送者未關閉的通道

func abandonedWorker(ch chan string) {    for data := range ch {        processData(data)    }      fmt.Println("Worker is done, shutting down")}func handler(inputData []string) {    ch := make(chan string, len(inputData))      for _, data := range inputData {        ch <- data    }      go abandonedWorker(ch)        return}

在上面的例子中,處理程序接收一個字符串切片,創建一個通道并將數據插入到通道中。vq428資訊網——每日最新資訊28at.com

處理程序然后通過Goroutine啟動一個工作程序。工作程序預計會處理數據,并且一旦處理完通道中的所有數據,就會終止。vq428資訊網——每日最新資訊28at.com

然而,即使消耗并處理了所有的數據,工作程序也永遠不會到達“第6行”!vq428資訊網——每日最新資訊28at.com

盡管通道是空的,但它沒有被關閉!工作程序繼續認為未來可能會有傳入的數據。因此,它坐下來并永遠等待。vq428資訊網——每日最新資訊28at.com

這是Goroutine再次泄漏的地方。vq428資訊網——每日最新資訊28at.com

在錯誤檢查之后放置發送者

這與我們之前的一些示例非常相似。vq428資訊網——每日最新資訊28at.com

func abandonedWorker(ch chan []int) {    data := <- ch    fmt.Println(data)}func handler() error {    ch := make(chan []int)    go abandonedWorker(ch)    records, err := getFromDB()    if err != nil {        return errors.New("Database error. Returning")    }    ch <- records    return nil}

在上面的例子中,處理程序首先啟動一個Goroutine工作程序來處理和消費一些數據。vq428資訊網——每日最新資訊28at.com

然后,處理程序從數據庫中查詢記錄,然后將記錄注入通道供工作程序使用。vq428資訊網——每日最新資訊28at.com

如果數據庫出現錯誤,處理程序將立即返回。通道將不再有任何發送者傳入數據。vq428資訊網——每日最新資訊28at.com

因此,工作程序被遺棄。vq428資訊網——每日最新資訊28at.com

解決方案:被遺棄的接收者

在這兩種情況下,接收者都被留下,因為他們“認為”通道將有傳入的數據。因此,它們阻塞并永遠等待。vq428資訊網——每日最新資訊28at.com

解決方案是一個簡單的單行代碼。vq428資訊網——每日最新資訊28at.com

defer close(ch)

當你啟動一個新的通道時,最好的做法是推遲關閉通道。vq428資訊網——每日最新資訊28at.com

這確保在數據發送完成或函數退出時關閉通道。vq428資訊網——每日最新資訊28at.com

接收者可以判斷一個通道是否已關閉,并相應地終止。vq428資訊網——每日最新資訊28at.com

func abandonedReceiver(ch chan int) {    // This will NOT be blocked FOREVER    data := <- ch      fmt.Println(data) }func handler() {    ch := make(chan int)        // Defer the CLOSING of channel    defer close(ch)      go abandonedReceiver(ch)    return}

結論

關于 Goroutine 泄漏就是這么多了!vq428資訊網——每日最新資訊28at.com

盡管它不像其他 Goroutine 錯誤那么強大,但這種泄漏仍然會大大耗盡應用程序的內存使用。vq428資訊網——每日最新資訊28at.com

記住,擁有強大的力量也伴隨著巨大的責任。vq428資訊網——每日最新資訊28at.com

保護我們的應用程序免受錯誤的責任在于你我——開發人員!vq428資訊網——每日最新資訊28at.com

本文鏈接:http://www.www897cc.com/showinfo-26-15597-0.html常見的 Goroutine 泄露,你應該避免

聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。郵件:2376512515@qq.com

上一篇: 并發編程:你真的能回答好AQS嗎(補充中斷機制)

下一篇: Python自動查重:原理、方法與實踐

標簽:
  • 熱門焦點
  • 轎車從天而降電動車主被撞身亡 超速搶道所致:現場視頻讓網友吵翻

    近日,上海青浦區法院判決轎車從天而降電動車主被撞身亡案,轎車車主被判有期徒刑一年。案件顯示當時男子駕駛轎車在上海某路段行駛,前車忽然轉彎提速超車,
  • 自動化在DevOps中的力量:簡化軟件開發和交付

    自動化在DevOps中扮演著重要角色,它提升了DevOps的效能。通過自動化工具和方法,DevOps團隊可以實現以下目標:消除手動和重復性任務。簡化流程。在整個軟件開發生命周期中實現更
  • .NET 程序的 GDI 句柄泄露的再反思

    一、背景1. 講故事上個月我寫過一篇 如何洞察 C# 程序的 GDI 句柄泄露 文章,當時用的是 GDIView + WinDbg 把問題搞定,前者用來定位泄露資源,后者用來定位泄露代碼,后面有朋友反
  • 中國家電海外掘金正當時|出海專題

    作者|吳南南編輯|胡展嘉運營|陳佳慧出品|零態LT(ID:LingTai_LT)2023年,出海市場戰況空前,中國創業者在海外紛紛摩拳擦掌,以期能夠把中國的商業模式、創業理念、戰略打法輸出海外,他們依
  • “又被陳思誠騙了”

    作者|張思齊 出品|眾面(ID:ZhongMian_ZM)如今的國產懸疑電影,成了陳思誠的天下。最近大爆電影《消失的她》票房突破30億斷層奪魁暑期檔,陳思誠再度風頭無兩。你可以說陳思誠的
  • 阿里大調整

    來源:產品劉有媒體報道稱,近期淘寶天貓集團啟動了近年來最大的人力制度改革,涉及員工績效、層級體系等多個核心事項,目前已形成一個初步的&ldquo;征求意見版&rdquo;:1、取消P序列
  • 認真聊聊東方甄選:如何告別低垂的果實

    來源:山核桃作者:財經無忌爆火一年后,俞敏洪和他的東方甄選依舊是頗受外界關心的&ldquo;網紅&rdquo;。7月5日至9日,為期5天的東方甄選&ldquo;甘肅行&rdquo;首次在自有App內直播,
  • AMD的AI芯片轉單給三星可能性不大 與臺積電已合作至2nm制程

    據 DIGITIMES 消息,英偉達 AI GPU 出貨逐季飆升,接下來 AMD MI 300 系列將在第 4 季底量產。而半導體業內人士表示,近日傳出 AMD 的 AI 芯片將轉單給
  • OPPO K11采用全方位護眼屏:三大護眼能力減輕視覺疲勞

    日前OPPO官方宣布,全新的OPPO K11將于7月25日正式發布,將主打旗艦影像,和同檔位競品相比,其最大的賣點就是將配備索尼IMX890主攝,堪稱是2000檔位影像表
Top 主站蜘蛛池模板: 宁国市| 武定县| 河曲县| 达拉特旗| 华安县| 斗六市| 鄱阳县| 邵武市| SHOW| 彭州市| 平南县| 扬州市| 屯留县| 资中县| 肇州县| 纳雍县| 嘉鱼县| 广南县| 积石山| 浪卡子县| 都匀市| 黔西| 舒兰市| 婺源县| 蒙城县| 会昌县| 荥经县| 岑巩县| 岑溪市| 镇原县| 花莲县| 黄梅县| 全南县| 大荔县| 黎平县| 宁安市| 湛江市| 上虞市| 达州市| 弋阳县| 华池县|