1 回答
TA贡献1793条经验 获得超6个赞
当您运行常规程序时,它会等待来自通道的输入。而且因为只有一个 goroutine,所以无法从通道接收输入(没有其他线程可以发送给它)。因此报告了死锁。
另一方面,测试运行器使用 goroutines 来执行测试。所以产生了不止一个 goroutine 并且没有检测到死锁(运行时假设其他 goroutine 可以发送到通道)。
从评论中回答您的问题: go run 和 go test 不应该达到相同的效果。go run 执行你的程序, go test 执行测试你的代码的程序。这些命令执行两个不同的程序。
我不确定您是否可以通过测试检测到这种错误(死锁)。
编辑: go test等待测试完成(您可以使用-timeout d选项配置多长时间)。所以我假设它产生了等待timer.Timer过期的 goroutine,所以没有死锁(总是有一个 goroutine 有机会被执行)。
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 关注
- 165 浏览
添加回答
举报
