Go语言并发之道学习-----基本概念

并发概述

并发:通常指的是一个或多个进程同时发生的过程
1、竞争条件:当两个或多个操作必须按正确的顺序执行,而程序并未保证顺序

var data int
go func(){
	data++
}()
if data == 0{
	fmt.Printf("The data:%d\n",data)
}

这段代码可能会有三种情况

  • 不打印
  • 打印 The data:0
  • 打印 The data:1
    因此代码中会有不确定性,这应该是被避免出现的,竞争出现的主要原因是在于顺序性的思维方式,竞争条件是最难发现的并发bug类型之一
    2、原子性
    如果被认定为是原子的或具有原子性时,意味着在运行环境中是不可分割的或不可中断的
    上下文:某个东西在此上下文中是原子性的,而在其他上下文中就不是原子性了。比如在应用程序的上下文中某操作是原子操作,而在操作系统的上下文中就不是原子性了。即操作原子性可以根据当前定义的范围而改变
    原子性的设计:首先定义上下文或者范围,其次是考虑操作是否是原子性的
    不可分割和不可中断:
    i++在程序内部的操作可分为
    - 检索i的值
    - 增加i的值
    - 存储i的值
    每一步都是原子的,但是结合在一起就可能不是了,取决于上下文
data := 0
	w := sync.WaitGroup{}
	for i := 0; i < 100000; i++{
		w.Add(1)
		go func() {
			data++
			w.Done()
		}()
	}
	w.Wait()
	fmt.Println("data:",data)

打印的data值是不确定的

3、内存访问同步
数据竞争的例子:

var data int
go func(){
	data++
}()
if data == 0{
	fmt.Printf("The data:%d\n",data)
} else{
	fmt.Printf("the data:%d\n",data)
}

程序总是会有一个输出,在有数据竞争的情况下输出将不会正确
程序中有三个临界区(独占访问共享资源的部分):
- goroutine在增加数据变量
- if在检查data==0是否成立
- fmt.Printf检索并输出数据的值
通常的会使用锁机制来同步内存访问,但是锁机制自动解决数据竞争或逻辑正确性问题,而且会造成性能问题

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值