登录
首页 >  Golang >  Go问答

检测循环中的无效数值

来源:stackoverflow

时间:2024-03-01 18:00:26 175浏览 收藏

在Golang实战开发的过程中,我们经常会遇到一些这样那样的问题,然后要卡好半天,等问题解决了才发现原来一些细节知识点还是没有掌握好。今天golang学习网就整理分享《检测循环中的无效数值》,聊聊,希望可以帮助到正在努力赚钱的你。

问题内容

我偶然发现了一个有缺陷的 golang 代码,该代码试图使用互斥体来防止对 goroutine 中打印的变量进行更改:

runtime.gomaxprocs(1)

    mutex := new(sync.mutex)
    for i := 0; i < 10; i++ {
        for j := 0; j < 10; j++ {
            mutex.lock()
            go func() {
                fmt.println(i, j, i + j);
                mutex.unlock()
            }()
        }
    }

我很清楚,互斥体不会直接锁定,而是在下一次迭代中,当值已经增加时锁定。不清楚的是,根据输出,为什么 j 变量达到 10:

...
0 7 7
0 8 8
0 9 9
1 10 11   <--- isn't supposed to be here
...
1 9 10
2 10 12
...

我尝试调试代码,当 i 的外循环增加其值时,会打印 j = 10 。看起来好像外部循环正在释放线程,允许 goroutine 执行并看到无效值 10。有人可以澄清这种行为吗?


解决方案


您存在数据竞争。结果未定义。

$ go run -race racer.go
==================
warning: data race
read at 0x00c000016110 by goroutine 7:
  main.main.func1()
      /home/peter/gopath/racer.go:17 +0x7f

previous write at 0x00c000016110 by main goroutine:
  main.main()
      /home/peter/gopath/racer.go:14 +0xf1

goroutine 7 (running) created at:
  main.main()
      /home/peter/gopath/racer.go:16 +0xcd
==================
0 1 1
0 2 2
0 3 3
0 4 4
0 5 5
0 6 6
0 7 7
0 8 8
0 9 9
==================
warning: data race
read at 0x00c000016108 by goroutine 16:
  main.main.func1()
      /home/peter/gopath/racer.go:17 +0x50

previous write at 0x00c000016108 by main goroutine:
  main.main()
      /home/peter/gopath/racer.go:13 +0x140

goroutine 16 (running) created at:
  main.main()
      /home/peter/gopath/racer.go:16 +0xcd
==================
1 10 11
1 1 2
1 2 3
1 3 4
1 4 5
1 5 6
1 6 7
1 7 8
1 8 9
1 9 10
2 10 12
2 1 3
2 2 4
2 3 5
2 4 6
2 5 7
2 6 8
2 7 9
2 8 10
2 9 11
3 10 13
3 1 4
3 2 5
3 3 6
3 4 7
3 5 8
3 6 9
3 7 10
3 8 11
3 9 12
4 10 14
4 1 5
4 2 6
4 3 7
4 4 8
4 5 9
4 6 10
4 7 11
4 8 12
4 9 13
5 10 15
5 1 6
5 2 7
5 3 8
5 4 9
5 5 10
5 6 11
5 7 12
5 8 13
5 9 14
6 10 16
6 1 7
6 2 8
6 3 9
6 4 10
6 5 11
6 6 12
6 7 13
6 8 14
6 9 15
7 10 17
7 1 8
7 2 9
7 3 10
7 4 11
7 5 12
7 6 13
7 7 14
7 8 15
7 9 16
8 10 18
8 1 9
8 2 10
8 3 11
8 4 12
8 5 13
8 6 14
8 7 15
8 8 16
8 9 17
9 10 19
9 1 10
9 2 11
9 3 12
9 4 13
9 5 14
9 6 15
9 7 16
9 8 17
9 9 18
found 2 data race(s)
exit status 66
$

racer.go

package main

import (
    "fmt"
    "runtime"
    "sync"
)

func main() {
    runtime.GOMAXPROCS(1)

    mutex := new(sync.Mutex)
    for i := 0; i < 10; i++ {
        for j := 0; j < 10; j++ {
            mutex.Lock()
            go func() {
                fmt.Println(i, j, i+j)
                mutex.Unlock()
            }()
        }
    }
}

Go: Data Race Detector

今天关于《检测循环中的无效数值》的内容介绍就到此结束,如果有什么疑问或者建议,可以在golang学习网公众号下多多回复交流;文中若有不正之处,也希望回复留言以告知!

声明:本文转载于:stackoverflow 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>