go - 为什么当我有两个 go-routines 时没有执行循环中的代码
问题描述
我在 golang 中遇到问题
var a = 0
func main() {
go func() {
for {
a = a + 1
}
}()
time.Sleep(time.Second)
fmt.Printf("result=%d\n", a)
}
- 预期:结果=(一个大整数)
- 结果:结果=0
解决方案
你有一个竞争条件,用 -race 标志运行你的程序
go run -race main.go
==================
WARNING: DATA RACE
Read at 0x0000005e9600 by main goroutine:
main.main()
/home/jack/Project/GoProject/src/gitlab.com/hooshyar/GoNetworkLab/StackOVerflow/race/main.go:17 +0x6c
Previous write at 0x0000005e9600 by goroutine 6:
main.main.func1()
/home/jack/Project/GoProject/src/gitlab.com/hooshyar/GoNetworkLab/StackOVerflow/race/main.go:13 +0x56
Goroutine 6 (running) created at:
main.main()
/home/jack/Project/GoProject/src/gitlab.com/hooshyar/GoNetworkLab/StackOVerflow/race/main.go:11 +0x46
==================
result=119657339
Found 1 data race(s)
exit status 66
什么是解决方案?
有一些解决方案,一个解决方案是使用互斥锁:
var a = 0
func main() {
var mu sync.Mutex
go func() {
for {
mu.Lock()
a = a + 1
mu.Unlock()
}
}()
time.Sleep(3*time.Second)
mu.Lock()
fmt.Printf("result=%d\n", a)
mu.Unlock()
}
在任何读写锁定互斥锁然后解锁它之前,现在你没有任何比赛并且resault最终会变得很大。
有关更多信息,请阅读本主题。
Go(Golang)中的数据竞争以及如何解决它们
和这个
推荐阅读
- java - SQLite - 无法更新具有长文本的行 id 列
- coldfusion - Coldfusion框架应用配置
- android - 带有部分标题的列表视图
- python - 如何在 Python 中遍历所有单词直至字母表的排列?
- excel - 数组公式根据列表检查行中的多列并查找匹配项
- c# - Azure 上的 AspNetIdentity 登录失败 - 初始化字符串的格式不符合从索引 0 开始的规范
- java - 有没有办法将动作与发生在任何地方的特定异常相关联?
- reactjs - 如何测试动态页面标题?
- java - 使用 JSF+Spring-Boot、PrimeFaces 和 Joinfaces 扫描坏幻数的类路径
- typescript - 对于打字稿中的黄瓜数据表,始终返回 true