gpt4 book ai didi

go test 和 go run 执行以下 channel 代码,但结果不同。为什么?

转载 作者:行者123 更新时间:2023-12-01 22:40:37 50 4
gpt4 key购买 nike

main.go

func main() {
fmt.Println("hello")
ch := make(chan struct{}, 1)
<-ch
}
main_test.go

func Test_Main(t *testing.T) {
main()
}

去运行 main.go
  hello
fatal error: all goroutines are asleep - deadlock!
goroutine 1 [chan receive]:
main.main()


去测试 -v main_test.go -run=Test_Main
=== RUN   Test_Main
hello


go test 不会报错,会一直运行。
查阅了很多资料,也没有找到解释这个现象的答案。可能是我的方式不对?这个 channel 方式是在项目中使用的。
谢谢。

最佳答案

当您运行常规程序时,它会等待来自 channel 的输入。而且因为只有一个 goroutine,所以无法从 channel 接收输入(没有其他线程可以发送给它)。因此报告了死锁。

另一方面,测试运行器使用 goroutines 来执行测试。所以产生了不止一个 goroutine 并且没有检测到死锁(运行时假设其他 goroutine 可以发送到 channel )。

从评论中回答您的问题: go run 和 go test 不应该达到相同的效果。 go run 执行你的程序, go test 执行测试你的代码的程序。这些命令执行两个不同的程序。

我不确定您是否可以通过测试检测到这种错误(死锁)。

编辑:go test等待测试完成(您可以使用 -timeout d 选项配置多长时间)。所以我假设它会产生等待 timer.Timer 的 goroutine过期,所以没有死锁(总是有一个 goroutine 有机会被执行)。

编辑2:
试试这个程序:

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 秒。

编辑3:
或者看一下说明测试运行程序如何工作的流动代码:

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()
}

关于go test 和 go run 执行以下 channel 代码,但结果不同。为什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60448798/

50 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com