码农知识堂 - 1000bd
  •   Python
  •   PHP
  •   JS/TS
  •   JAVA
  •   C/C++
  •   C#
  •   GO
  •   Kotlin
  •   Swift
  • 【golang/问题记录】goroutine之间数据竞争问题


    说在前面

    • go版本:go1.18.4 windows/amd64

    测试代码

    • 开三个goroutine,一个不断赋值,一个隔一段时间将其置空,一个判断是否为空之后进行一些操作
      type MainStruct struct {
      	Child *ChildStruct
      }
      
      type ChildStruct struct {
      	Value int
      }
      
      func TestMain() {
      	tmp := &MainStruct{
      		Child: &ChildStruct{
      			Value: 0,
      		},
      	}
      
      	// 不断赋值
      	go func() {
      		for {
      			tmp = &MainStruct{
      				Child: &ChildStruct{
      					Value: 0,
      				},
      			}
      		}
      	}()
      	// 判空后进行一些操作
      	go func() {
      		for {
      			if tmp.Child != nil {
      				tmp.Child.Value = 0
      				tmp.Child.Value++
      			}
      		}
      	}()
      	// 不断置空
      	go func() {
      		for {
      			tmp.Child = nil
      		}
      	}()
      
      	for {
      		time.Sleep(time.Second * 10)
      	}
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28
      • 29
      • 30
      • 31
      • 32
      • 33
      • 34
      • 35
      • 36
      • 37
      • 38
      • 39
      • 40
      • 41
      • 42
      • 43
      • 44
      • 45
    • 上述代码在执行一段时间后直接panic,原因是tmp.Child为nil
      panic: runtime error: invalid memory address or nil pointer dereference
      [signal 0xc0000005 code=0x1 addr=0x0 pc=0xa8a0bc]
      
      goroutine 36 [running]:
      main.TestMain.func2()
              D:/gamemanager/src/go/test.go:393 +0x1c
      created by main.TestMain
              D:/gamemanager/src/go/test.go:389 +0xf6
      exit status 2
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
    • 但是当把判空并进行操作的那个goroutine代码改一下后,就没有panic过了
      go func() {
      	for {
      		if tmp.Child != nil {
      			// tmp.Child.Value = 0
      			tmp.Child.Value++
      		}
      	}
      }()
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
    • 对于在if这个判定中访问tmp.Child会出问题,我是明确的,因为这个时候tmp.Child的值是不确定的,但是问题是为什么在去掉一行之后却没有问题。

    尝试

    • 去stackoverflow上问了下,大佬们说因为data race的存在,tmp.Child的值不确定,所以探讨这个问题没有意义。附上链接
  • 相关阅读:
    IDEA 搭建 SpringCloud 项目【超详细步骤】
    网络安全(黑客)自学
    【力扣刷题】Day31——DP专题
    论文选题和论文题目的区别?
    Pjax 下动态加载插件方案
    B+树索引(11)之索引挑选(上)
    靠这份业界最强算法及数据结构宝典,我挺进字节跳动
    Python模块 adorner 的使用示例
    短视频矩阵系统源码----技术独立部署搭建
    Vue+Element Progress 进度条显示文字 %修改,使用format方法显示文字可自定义
  • 原文地址:https://blog.csdn.net/qq_33446100/article/details/127865705
  • 最新文章
  • 攻防演习之三天拿下官网站群
    数据安全治理学习——前期安全规划和安全管理体系建设
    企业安全 | 企业内一次钓鱼演练准备过程
    内网渗透测试 | Kerberos协议及其部分攻击手法
    0day的产生 | 不懂代码的"代码审计"
    安装scrcpy-client模块av模块异常,环境问题解决方案
    leetcode hot100【LeetCode 279. 完全平方数】java实现
    OpenWrt下安装Mosquitto
    AnatoMask论文汇总
    【AI日记】24.11.01 LangChain、openai api和github copilot
  • 热门文章
  • 十款代码表白小特效 一个比一个浪漫 赶紧收藏起来吧!!!
    奉劝各位学弟学妹们,该打造你的技术影响力了!
    五年了,我在 CSDN 的两个一百万。
    Java俄罗斯方块,老程序员花了一个周末,连接中学年代!
    面试官都震惊,你这网络基础可以啊!
    你真的会用百度吗?我不信 — 那些不为人知的搜索引擎语法
    心情不好的时候,用 Python 画棵樱花树送给自己吧
    通宵一晚做出来的一款类似CS的第一人称射击游戏Demo!原来做游戏也不是很难,连憨憨学妹都学会了!
    13 万字 C 语言从入门到精通保姆级教程2021 年版
    10行代码集2000张美女图,Python爬虫120例,再上征途
Copyright © 2022 侵权请联系2656653265@qq.com    京ICP备2022015340号-1
正则表达式工具 cron表达式工具 密码生成工具

京公网安备 11010502049817号