1 回答

TA貢獻1793條經(jīng)驗 獲得超6個贊
當您運行常規(guī)程序時,它會等待來自通道的輸入。而且因為只有一個 goroutine,所以無法從通道接收輸入(沒有其他線程可以發(fā)送給它)。因此報告了死鎖。
另一方面,測試運行器使用 goroutines 來執(zhí)行測試。所以產(chǎn)生了不止一個 goroutine 并且沒有檢測到死鎖(運行時假設其他 goroutine 可以發(fā)送到通道)。
從評論中回答您的問題: go run 和 go test 不應該達到相同的效果。go run 執(zhí)行你的程序, go test 執(zhí)行測試你的代碼的程序。這些命令執(zhí)行兩個不同的程序。
我不確定您是否可以通過測試檢測到這種錯誤(死鎖)。
編輯: go test等待測試完成(您可以使用-timeout d選項配置多長時間)。所以我假設它產(chǎn)生了等待timer.Timer過期的 goroutine,所以沒有死鎖(總是有一個 goroutine 有機會被執(zhí)行)。
Edit2: 試試這個程序:
package main
import (
"fmt"
"time"
)
func main() {
go func() {
t := time.NewTimer(10 * time.Second)
<-t.C
}()
fmt.Println("hello")
ch := make(chan struct{}, 1)
<-ch
}
它在報告死鎖之前等待 10 秒。
Edit3: 或者看一下說明測試運行器如何工作的流動代碼:
package main
import (
"fmt"
"time"
)
func original_main_func() {
fmt.Println("hello")
ch := make(chan struct{}, 1)
<-ch
}
func test() {
original_main_func()
}
func test_runner() {
ch := make(chan struct{}, 1)
go func() {
test()
close(ch)
}()
t := time.NewTimer(10 * time.Second)
select {
case <-t.C:
panic("timeout")
case <-ch:
fmt.Println("test executed")
}
}
func main() {
test_runner()
}
- 1 回答
- 0 關注
- 132 瀏覽
添加回答
舉報