1 回答

TA貢獻(xiàn)2080條經(jīng)驗(yàn) 獲得超4個(gè)贊
您的代碼的問(wèn)題是雙重的。
首先,理論上存在goroutine泄漏,因?yàn)槿魏蜗蛉萘繛榱愕耐ǖ溃o(wú)緩沖通道或已滿緩沖通道)發(fā)送值的嘗試都會(huì)阻塞發(fā)送 goroutine,直到在該通道上完成接收操作。
所以,是的,根據(jù)通道工作方式的定義,所有三個(gè) goroutine 都將在numChan <- num
語(yǔ)句中被阻止。
其次,由于 Go 的一些修改,panic
默認(rèn)情況下未處理的只轉(zhuǎn)儲(chǔ)恐慌 goroutine 的堆棧跟蹤。如果你想轉(zhuǎn)儲(chǔ)所有活動(dòng)的 goroutines 的堆棧,你必須調(diào)整運(yùn)行時(shí)——來(lái)自包的文檔runtime
:
該
GOTRACEBACK
變量控制當(dāng) Go 程序由于未恢復(fù)的恐慌或意外的運(yùn)行時(shí)條件而失敗時(shí)生成的輸出量。默認(rèn)情況下,失敗會(huì)打印當(dāng)前 goroutine 的堆棧跟蹤,省略運(yùn)行時(shí)系統(tǒng)內(nèi)部的函數(shù),然后以退出代碼 2 退出。如果沒(méi)有當(dāng)前 goroutine 或失敗是,則失敗會(huì)打印所有 goroutine 的堆棧跟蹤運(yùn)行時(shí)內(nèi)部。GOTRACEBACK=none
完全省略 goroutine 堆棧跟蹤。GOTRACEBACK=single
(默認(rèn)值)的行為如上所述。GOTRACEBACK=all
為所有用戶創(chuàng)建的 goroutines 添加堆棧跟蹤。GOTRACEBACK=system
類似于“all”,但為運(yùn)行時(shí)函數(shù)添加堆棧幀并顯示運(yùn)行時(shí)內(nèi)部創(chuàng)建的 goroutine。GOTRACEBACK=crash
類似于“系統(tǒng)”,但以特定于操作系統(tǒng)的方式崩潰而不是退出。例如,在 Unix 系統(tǒng)上,崩潰SIGABRT
引發(fā)核心轉(zhuǎn)儲(chǔ)。由于歷史原因,GOTRACEBACK
設(shè)置 0、1 和 2 分別是 none、all 和 system 的同義詞。The runtime/debug
package 的SetTraceback
功能允許在運(yùn)行時(shí)增加輸出量,但它不能減少到低于環(huán)境變量指定的量。
另請(qǐng)注意,您絕不能使用計(jì)時(shí)器進(jìn)行(模擬)同步:在玩具示例中,這可能有效,但在現(xiàn)實(shí)生活中,沒(méi)有什么能阻止您的三個(gè) goroutine 在您的主 goroutine 在調(diào)用中花費(fèi)的時(shí)間跨度內(nèi)沒(méi)有機(jī)會(huì)運(yùn)行到time.Sleep
——所以結(jié)果可能是任何數(shù)量的派生 goroutines 已經(jīng)運(yùn)行:從 0 到 3。
在那里添加一個(gè)事實(shí),即當(dāng)main
退出運(yùn)行時(shí)時(shí),運(yùn)行時(shí)只會(huì)殺死所有未完成的活動(dòng) goroutines,并且測(cè)試結(jié)果充其量可能是令人驚訝的。
因此,一個(gè)適當(dāng)?shù)慕鉀Q方案是
僅在需要的地方打印堆棧,
確保通過(guò)匹配的接收同步發(fā)送:
package main
import (
? ? "fmt"
? ? "log"
? ? "runtime"
)
func dumpStacks() {
? ? buf := make([]byte, 32 * 1024)
? ? n := runtime.Stack(buf, true)
? ? log.Println(string(buf[:n]))
}
func main() {
? ? numCount := 3
? ? numChan := make(chan int, numCount)
? ? for i := 0; i < numCount; i++ {
? ? ? ? go func(num int) {
? ? ? ? ? ? fmt.Printf("Adding num: %d to chan\n", num)
? ? ? ? ? ? numChan <- num
? ? ? ? ? ? fmt.Printf("Adding num: %d to chan Done\n", num)
? ? ? ? }(i)
? ? }
? ? dumpStacks()
? ? for i := 0; i < numCount; i++ {
? ? ? ? <-numChan
? ? }
}
- 1 回答
- 0 關(guān)注
- 144 瀏覽
添加回答
舉報(bào)