面试题答案
一键面试使用race detector检测Goroutine竞态条件的步骤和命令
- 编译时启用race detector:在编译Go程序时,使用
-race
标志。例如,对于一个可执行程序:
go build -race
如果是测试一个包中的单元测试,使用:
go test -race
- 运行程序:编译完成后,运行生成的可执行文件,race detector会在运行过程中检测竞态条件,并在发现问题时输出详细的报告。
引发竞态条件的代码场景示例
package main
import (
"fmt"
"sync"
)
var count int
func increment(wg *sync.WaitGroup) {
defer wg.Done()
for i := 0; i < 1000; i++ {
count++
}
}
func main() {
var wg sync.WaitGroup
for i := 0; i < 10; i++ {
wg.Add(1)
go increment(&wg)
}
wg.Wait()
fmt.Println("Final count:", count)
}
在上述代码中,多个Goroutine同时对count
变量进行读写操作,没有进行同步控制,这就会导致竞态条件。
通过race detector发现问题
- 编译并运行:
- 首先编译程序:
go build -race
- 然后运行生成的可执行文件:
./<executable_name>
- 查看race detector报告:当运行程序时,如果存在竞态条件,race detector会输出类似如下的报告:
==================
WARNING: DATA RACE
Read at 0x00c000018098 by goroutine 8:
main.increment()
/path/to/your/file.go:10 +0x55
Previous write at 0x00c000018098 by goroutine 7:
main.increment()
/path/to/your/file.go:10 +0x55
Goroutine 8 (running) created at:
main.main()
/path/to/your/file.go:18 +0x9e
Goroutine 7 (finished) created at:
main.main()
/path/to/your/file.go:18 +0x9e
==================
Final count: 8765
Found 1 data race(s)
exit status 66
报告中会指出发生竞态的变量、读写操作的位置以及相关的Goroutine信息,帮助开发者定位和解决问题。