我有以下3个文件:第一个月
module example
go 1.19
main.go
package main
import "fmt"
func number(out chan int) bool {
defer close(out)
for i := 0; i < 5; i++ {
out <- i
}
return true
}
func main() {
in := make(chan int)
var ret bool
go func() {
ret = number(in)
}()
for i := range in {
fmt.Println(i)
}
if !ret {
fmt.Println(ret)
}
}
和main_test.go
package main
import "testing"
func TestMain(t *testing.T) {
t.Run("test", func(t *testing.T) {
main()
})
}
我似乎遇到了ret
变量的争用情况。为什么这是一个问题,range in
不应该阻塞直到number
函数中的通道关闭。因此ret
将在读取之前返回状态?还有,是否有一种方法可以在不使用同步包或另一个通道的情况下解决这个问题?
当我使用-race选项运行测试时,得到以下错误$ go test -race
0
1
2
3
4
==================
WARNING: DATA RACE
Read at 0x00c00002023f by goroutine 8:
example.main()
/example/main.go:27 +0x174
example.TestMain.func1()
/example/main_test.go:13 +0x24
testing.tRunner()
/usr/local/go/src/testing/testing.go:1446 +0x216
testing.(*T).Run.func1()
/usr/local/go/src/testing/testing.go:1493 +0x47
Previous write at 0x00c00002023f by goroutine 9:
example.main.func1()
/example/main.go:20 +0x47
Goroutine 8 (running) created at:
testing.(*T).Run()
/usr/local/go/src/testing/testing.go:1493 +0x75d
example.TestMain()
/example/main_test.go:12 +0x64
testing.tRunner()
/usr/local/go/src/testing/testing.go:1446 +0x216
testing.(*T).Run.func1()
/usr/local/go/src/testing/testing.go:1493 +0x47
Goroutine 9 (finished) created at:
example.main()
/example/main.go:19 +0xfe
example.TestMain.func1()
/example/main_test.go:13 +0x24
testing.tRunner()
/usr/local/go/src/testing/testing.go:1446 +0x216
testing.(*T).Run.func1()
/usr/local/go/src/testing/testing.go:1493 +0x47
==================
--- FAIL: TestMain (0.00s)
--- FAIL: TestMain/test (0.00s)
testing.go:1319: race detected during execution of test
testing.go:1319: race detected during execution of test
FAIL
exit status 1
FAIL example 1.555s
1条答案
按热度按时间ztmd8pv51#
当
ret
被读入main
时,可以保证通道被关闭,但不能保证对ret
的分配完成,因此,这是一个竞争。