go 并发编程 之 数据竞争 data race (三)

本文探讨了Go语言中的数据竞争问题,指出数据竞争可能导致的不可预测结果。通过示例展示了数据竞争如何发生,包括全局变量和临时变量的情况,并介绍了Go的race detector用于检测数据竞争。文章还讨论了单机字相关的数据竞争,尤其是接口类型在并发中的影响,强调了没有安全的数据竞争,建议通过同步原语避免此类问题。
摘要由CSDN通过智能技术生成

前言

两个或多个 goroutine 访问同一个资源(如变量或数据结构),并尝试对该资源进行读写而不考虑其他 goroutine。这种类型的代码可以创建你见过的最疯狂和最随机的 bug。通常需要大量的日志记录和运气才能找到这些类型的bug。


提示:以下是本篇文章正文内容,下面案例可供参考



一、data race 会出现什么结果呢?



        例子 一

        

package main

import (
	"fmt"
	"sync"
)

var Counter int = 0
var wg sync.WaitGroup

func main() {


	for i := 0; i < 100000; i++ {
		for routine := 1; routine <= 2; routine++ {

			wg.Add(1)
			go Routine(routine)

		}
		wg.Wait()
	}
	fmt.Println(Counter)
}
//399718 399574 399634
func Routine(id int) {

	for conut := 0; conut < 2; conut++ {
		Counter++
	}
	//399618 399650
	wg.Done()
}

399718 399574 399634 这是上面代码 执行3次的结果 每次都不一样

我们来分析一下:

最好的情况 4 Routine1 读 和 写  执行完 Routine2 才开始执行 读取到的是结果加2的数据 在次累加

最坏的情况:2  Routine1 读 和 写 中间 Routine2 开始执行了 读取到未累加的数据 

这里还有一个问题 i++ 是不是原子的?

在上面这个例子执行完就知道不是原子的了。我们来看看 低层汇编的代码

0x0031 00049 (main.go:29) MOVQ    "".Counter(SB), AX  
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值