MST

星途 面试题库

面试题:Go并发编程中,导致数据竞争的常见场景有哪些

在Go的并发编程里,数据竞争是常见问题。请阐述哪些场景容易引发数据竞争,并且说明如何使用Go提供的工具检测数据竞争。
43.3万 热度难度
编程语言Go

知识考点

AI 面试

面试题答案

一键面试

容易引发数据竞争的场景

  1. 多个goroutine同时读写共享变量:当多个goroutine同时对同一个变量进行读取和写入操作,且没有适当的同步机制时,就会引发数据竞争。例如:
package main

import (
    "fmt"
)

var num int

func main() {
    for i := 0; i < 10; i++ {
        go func() {
            num = num + 1
        }()
    }
    fmt.Println(num)
}

在这个例子中,多个goroutine同时对num变量进行写操作,没有同步机制,可能导致数据竞争。 2. 读写操作没有正确的顺序:即使只有一个写操作,但如果读操作和写操作的顺序没有正确同步,也可能出现数据竞争。例如:

package main

import (
    "fmt"
)

var flag bool
var data int

func writer() {
    data = 42
    flag = true
}

func reader() {
    if flag {
        fmt.Println(data)
    }
}

func main() {
    go writer()
    reader()
}

在这个例子中,reader函数依赖writer函数设置的flag来读取data,但由于没有适当同步,reader可能在data被完全写入之前读取,导致数据竞争。

使用Go提供的工具检测数据竞争

Go提供了go buildgo rungo test命令的-race标志来检测数据竞争。

  1. 构建时检测:在构建可执行文件时,使用-race标志:
go build -race main.go
  1. 运行时检测:在运行程序时,使用-race标志:
go run -race main.go
  1. 测试时检测:在运行测试时,使用-race标志:
go test -race

当检测到数据竞争时,Go会输出详细的报告,包括竞争发生的位置、涉及的goroutine等信息,帮助开发者定位和解决问题。