Go语言程序设计-第9章--使用共享变量实现并发

Go语言程序设计-第9章--使用共享变量实现并发

9.1 竟态

一个能在串行程序中正确工作的函数。如果这个函数在并发调用时仍然能正确工作,那么这个函数是并发安全的。在这里并发调用是指,在没有额外同步机制的情况下,从两个或者多个 goroutine 同时调用这个函数。如果一个类型的所有可访问方法和操作都是并发安全时,则它可称为并发安全的类型。

数据竟态发生于两个 goroutine 并发读写同一个变量,并且至少一个是写入时。有3个方法避免数据竟态。

第一种方法是不要修改变量。

第二种方法是避免多个 goroutine 访问同一个变量。

第三种方法是允许多个 goroutine 访问同一个变量,但是在同一时间只有一个 goroutine 可以访问,这种方法称为互斥机制。

9.2 互斥锁:sync.Mutex

在 Mutex 的 Lock 和 Unlock 之间,可能自由地读取和修改共享变量,这一部分称为临界区域。

9.3 读写互斥锁:sync.RWMutex

仅在绝大部分 goroutine 都在获取读锁并且锁竞争比较激烈时,RWMutex 才有优势。

9.4 内存同步

现代计算机一般会有多个处理器,每个处理器都有内存的本地缓存。为了提高效率,对内存的写入是缓存在每个处理器中的,只有在必要时才刷回内存。甚至刷回内存的顺序都可能与 goroutine 的写入顺序不一致。像通道或者互斥锁操作这样的同步原语都会使处理器把积累的写操作刷回内存并提交。

9.5 延迟初始化: sync.Once

go 复制代码
var loadIconsOnce sync.Once
var icons map[string]image.Image
// 并发安全
func Icon(name string) image.Image {
	loadiconsOnce.Do(loadIcons)
	return icons[name]
}

9.6 竟态检测器

把 -race 命令行添加到 go build, go run, go test 命令里面即可以使用该功能。

9.8 goroutine 与线程

9.8.1 可增长的栈

每个 OS 线程都有一个固定大小的栈内存(通常为 2MB),栈内存区域用于保存在其他函数调用期间哪些正在执行或临时暂停函数中的局部变量。这个固定的栈大小既又太大又太小。对于一个小的 goroutine,2MB的栈是一个巨大的浪费。对于复杂的和深度递归的函数,固定大小的栈始终不够大。

作为对比,一个 goroutine 在生命周期开始只有一个很小的栈,典型情况下为 2KB。与 OS 线程不同的是,goroutine 的栈不是固定大小的,它可以按需增大和缩小。goroutine 的栈可以到达 1GB,比线程典型的固定大小栈高出几个数量级。

Go 运行时包含一个自己的调度器,这个调度器使用一个称为 m:n 调度的技术(因为它可以复用/调度 m 个 goroutine 到 n 个 OS 线程)。Go 调度器与内核调度器的工作类似,但只关心单个 Go 程序的 goroutine 调度问题。

9.8.3 GOMAXPROCS

Go 调度器使用 GOMAXPROCS 参数确定使用多少个 OS 线程来同时执行 Go 代码。默认值是机器上 CPU 的数量。

bash 复制代码
GOMAXPROCS=1 go run hack-cliche.go

9.8.4 goroutine 没有标识

所以没有线程本地变量之类的结构。

相关推荐
To_OC16 小时前
跑了3个Docker容器后,我终于搞懂镜像和容器到底啥关系
后端·docker·容器
东风破_17 小时前
Docker 基础:为什么需要容器?
前端·后端·nginx
东风破_17 小时前
Docker 实战:使用 Nginx 作为容器入口代理 Node 服务
前端·后端·nginx
Lyyaoo.18 小时前
Spring Boot Validation 声明式参数校验
spring boot·后端·mysql
剩下了什么18 小时前
float32 与 float64 精度陷阱:如何在 Go 中避免错误使用
开发语言·后端·golang
Rain的Java大神之路18 小时前
介绍一下分布式事务
java·分布式·后端·spring·spring cloud·架构·springcloud
指尖时光.18 小时前
Three.js 超全入门综合案例
开发语言·javascript·ecmascript
暴力求解19 小时前
Linux网络---传输层协议TCP(二)
linux·服务器·开发语言·网络·tcp/ip
吴声子夜歌19 小时前
Java面试题——基础(一)
java·开发语言
小庞在加油19 小时前
WinDbg实战:QT/跨平台项目死锁与无响应问题排查指南
开发语言·qt·windbg·工具