亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

當主/父 goroutine 退出或返回時,未完成的 goroutine 會發生什么?

當主/父 goroutine 退出或返回時,未完成的 goroutine 會發生什么?

Go
飲歌長嘯 2022-12-19 20:04:53
我正在閱讀 go programming language 書,第 8.4 章中有這個例子func mirroredQuery() string{    responses := make(chan string, 3)    go func() { responses <- request("asia.gopl.io") }()    go func() { responses <- request("americas.gopl.io") }()    go func() { responses <- request("europe.gopl.io") }()    return <- responses // return the quickest response}還有這個評論如果我們使用一個無緩沖的通道,那么兩個較慢的 goroutines 會卡住試圖在一個沒有 goroutine 接收到的通道上發送它們的響應。這個評論本身是有道理的。但是mirroredQuery在緩沖情況下返回時兩個慢 goroutine 會發生什么?他們是否仍然跑完或被取消?編輯:我知道如果主要的 goroutnine 退出,那么無論它們是否運行,2 個較慢的 goroutines 都會“消失”。但是如果 main goroutine 還在運行,mirroredQuery()已經返回了,那 2 個 slow goroutines 會跑完嗎?基本上,退貨responses后還存在嗎?mirroredQuery如果是這樣,那么 2 個慢 goroutine 似乎原則上可以完成;如果不是,那么我們仍然像無緩沖情況一樣有泄漏?
查看完整描述

1 回答

?
幕布斯7119047

TA貢獻1794條經驗 獲得超8個贊

當主goroutine 返回時,整個運行時系統退出,相當突然。因此,任何卡在無緩沖或完整通道上等待發送的 goroutines 都將……不復存在。它們不會取消,不會運行,也不會等待。 把它想象成閃光紙著火了。


可以將此稱為 goroutine 泄漏,就像在程序終止“泄漏”之前可以引用任何未關閉或釋放的資源(例如打開的文件)一樣。但是由于整個過程終止,所以什么都沒有了。這里沒有真正的泄漏。這不是一個整潔的清理,但系統確實清理了。


作為示例,這是一個游樂場鏈接。


(如果你使用 Go 系統本身沒有定義的東西,你可能會以這種方式出現各種泄漏。例如,在舊的 System V 共享內存世界中,你可以創建共享內存段(shm_open)并且如果你從不關閉和取消鏈接他們,他們堅持。這是設計使然:他們的行為很像文件系統中的文件,只是它們存在于內存中,而不是存在于某種磁盤驅動器或其他任何東西上。但這遠遠超出了日常生活的正常范圍去編程。)


重新編輯:如果主goroutine沒有退出,所以程序仍在運行,其他 goroutines 繼續運行(或等待)直到他們用完所有事情并返回自己,或者做一些導致他們退出的事情(比如打電話runtime.Goexit,或者做一些引起恐慌的事情)。在這種情況下,就是:等待響應,然后將響應發送到通道中,然后返回。假設他們得到響應,他們會將響應放入通道中。假設將響應放入通道有效(不恐慌也不阻塞),然后它們將返回?;貋砗?,他們完成了,他們蒸發了。通道本身持續存在并持有字符串:這是資源泄漏,盡管是次要的,尤其是在玩具程序中。


如果沒有對通道本身的引用,則通道本身以及其中的字符串將被垃圾回收;這清理了泄漏的資源。由于我們假設它mirroredQuery已經返回,并且此時最后一個分離出來的 goroutine 也已經返回,這是對通道的最后引用,所以現在可以對通道進行 GC。(這種情況是否發生以及何時發生取決于運行時。)在這些 goroutine 中的最后一個完成之前,仍然至少有一個對通道的引用,從而阻止通道(以及字符串)被 GC。


如果通道是無緩沖的,那么兩個“丟失”的 goroutine 將阻止發送到通道的嘗試。這將導致那些 goroutines 保留下來,這反過來又會導致通道保留下來,這又會導致資源保持分配狀態,直到程序作為一個整體終止。所以那將是“壞的”。


關閉通道后,兩個“失敗”的 goroutine 可能會嘗試在關閉的通道上發送mirroredQuery ,這將導致它們調用恐慌代碼,從而終止程序。那也將是“壞的”。實現預期結果的最簡單代碼是使通道緩沖。


如果其中一個 goroutine 等待(響應)數年,那么這些年將保留那些“泄漏”的資源。這也將是“壞的”(輕微),所以我們想確保他們不會永遠等待。但這在小型演示程序中是不切實際的。


查看完整回答
反對 回復 2022-12-19
  • 1 回答
  • 0 關注
  • 155 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號