Go语言圣经 - 第9章 基于共享变量的并发 - 9.4 内存同步

第9章 基于共享变量的并发

前一章我们使用了goroutine和channel这样直接而自然的方式来实现并发的方法,有时候它们会存在一些问题

本章我们会更详细的介绍并发机制,尤其在goroutine之间共享变量,我们还会介绍goroutine和操作系统线程之间一些技术差别

9.4 内存同步

提一个问题,为什么我们在Balance中也用到了互斥条件,无论是基于channel还是基于互斥量。毕竟和存款不一样,它只由一个简单的操作组成,所以不会碰到goroutine在执行”期间“执行其它逻辑的风险。这里使用mutex有两方面考虑。第一是Balance不会在其它操作比如Withdraw”中间“执行。第二是同步不仅仅是一堆goroutine执行顺序的问题,同样也会涉及到内存的问题

了解过计算机组成原理的朋友们可能知道,为了提高效率cpu对内存的写入通常会先缓存在cache中,并在必要时一起放入主存,但是这种情况下可能这些数据被提交到主存时的顺序就不同了。像channel通信或者互斥量操作这样的原语会使处理器将其聚集的写入flush并commit,这样goroutine在某个时间点上的结果才能被其它处理器上运行的goroutine得到

var x,y int
go func() {
	x = 1
	fmt.Print("y:",y," ")
}()
go func() {
	y = 1
	fmt.Print("x:",x," ")
}()

上面这两个变量分别在两个goroutine中执行,我们希望结果是如下的一种

y:0 x:1
x:0 y:1
x:1 y:1
y:1 x:1

但是它输出的结果确是

x:0 y:0
y:0 x:0

那怎么解释这个现象呢?其实我们在前面也见到过了,如果goroutine中不使用channel或者互斥锁的话,它内部语句执行顺序也是我们很难去推测的,所以对于需要通过并发提升效率的同时又想局部限制程序语句的执行顺序,请务必使用channel或者互斥锁

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值