这是Go语言中的竞态条件吗?

huangapple go评论69阅读模式
英文:

Is this a race condition in go

问题

func main() {
	m := map[string]int{
		"foo": 42,
		"bar": 1337,
	}

	go func() {
		time.Sleep(1 * time.Second)
		tmp := map[string]int{
			"foo": 44,
			"bar": 1339,
		}

		m = tmp
	}()

	for {
		val := m["foo"]
		fmt.Println(val)
	}
}

我在许多包中看到了这段代码。

为什么这不被视为竞态条件?

go run -race . 没有报错。

英文:
func main() {
	m := map[string]int{
		"foo": 42,
		"bar": 1337,
	}

	go func() {
		time.Sleep(1 * time.Second)
		tmp := map[string]int{
			"foo": 44,
			"bar": 1339,
		}

		m = tmp
	}()

	for {
		val := m["foo"]
		fmt.Println(val)
	}
}

I saw this in many packages.

Why this is not considered as a race condition?

go run -race . giving no error.

答案1

得分: 3

如@Volker所指出的,这是一个数据竞争。由于只有一个写入操作,很难检测到。这里是一个修改后的示例,可以更容易地触发数据竞争错误:

package main

import (
	"fmt"
	"time"
)

func main() {
	m := map[string]int{
		"foo": 42,
		"bar": 1337,
	}

	done := make(chan any)

	go func() {
		for i := 0; i < 100; i++ {
			time.Sleep(time.Microsecond)
			tmp := map[string]int{
				"foo": 44,
				"bar": 1339,
			}

			m = tmp
		}

		close(done)
	}()

	for {
		select {
		case <-done:
			return
		default:
			val := m["foo"]
			fmt.Println(val)
		}
	}
}
英文:

As pointed out by @Volker, this is a data race. And since there is only one write, it's hard to be detected. Here is a modified demo to make it easy to trigger the data race error:

package main

import (
	&quot;fmt&quot;
	&quot;time&quot;
)

func main() {
	m := map[string]int{
		&quot;foo&quot;: 42,
		&quot;bar&quot;: 1337,
	}

	done := make(chan any)

	go func() {
		for i := 0; i &lt; 100; i++ {
			time.Sleep(time.Microsecond)
			tmp := map[string]int{
				&quot;foo&quot;: 44,
				&quot;bar&quot;: 1339,
			}

			m = tmp
		}

		close(done)
	}()

	for {
		select {
		case &lt;-done:
			return
		default:
			val := m[&quot;foo&quot;]
			fmt.Println(val)
		}
	}
}

huangapple
  • 本文由 发表于 2023年6月1日 18:34:29
  • 转载请务必保留本文链接:https://go.coder-hub.com/76381002.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定