大家好,今天将梳理出的 Go语言并发知识内容,分享给大家。 请多多指教,谢谢。
本章节内容
- WaitGroup
- Mutex
- Locker
- RWMutex
Go在内存访问同步基元的基础上构建了一组新的并发基元,并为使用者提供扩展的内容。 Go sync标准库,主要包含对低级别内存访问同步最有用的并发原语。 如果你使用的是主要通过内存访问同步处理并发的语言,那么这些类型是不错的选择。
WaitGroup
WaitGroup 类型原型
Add()Done()Wait()
Add()Wait()Add()Wait()Add()
WaitGroup 使用
Add()Add()
Mutex
Mutex
Mutex 很容易理解,代表 “mutual exclusion(互斥)”。互斥提供了一种并发安全的方式来表示对共享资源访问的独占。
可以理解为在代码块设置临界区,在同一时刻只能由一个 goroutine 去操作。
Mutex 类型原型
Lock()
TryLock()
Unlock()
Mutex 使用
举例:两个 goroutine,它们试图增加和减少一个公共值,并使用 Mutex 来同步访问。
这里,count变量由互斥锁保护
输出
这里因为goroutine调度机制原因,在大家各自设备编码后结果会发生变化。
注意,被锁定部分是程序的性能瓶颈,进入和退出锁定的成本有点高,因此通常尽量减少锁定涉及的范围。
Locker
Locker 接口原型
Locker接口中定义了锁定和解锁的方法。
RWMutex
RWMutexRWMutex
RWMutexMutex
常见的服务对资源的读写比列会非常高,如果大多数的请求都是读请求,它们之间不会互相影响,那么就可以将资源的操作进行读和写分离,出于这样的考虑,可以使用RWMutex。
读写锁控制下的多个写操作之间都是互斥的,并且写操作与读操作之间也都是互斥的。但多个读操作之间不存在互斥关系。读写锁可以在大大降低因使用锁而造成的性能损耗,完成对共享资源的访问控制。
RWMutex 类型原型
Lock()
RLock()
RLocker()
RUnlock()
TryLock()
TryRLock()
Unlock()
与 Mutex 一样,RWMutex的互斥体与特定的 goroutine 没有关联。一个 goroutine 可以重新锁定(锁定),然后安排另一个 goroutine 运行锁定(解锁)。
RWMutex 使用
举例:读写锁的使用
输出
- 启用了 3 个 goroutine 用于读写锁 rwm 的读锁定和读解锁操作
- 读解锁操作会延迟 2s 进行模拟真是的情况
- 先让主 goroutine 睡眠 100ms,让 3个 goroutine先有足够时间执行
- 之后 rwm 的写锁定操作让主 goroutine 阻塞,因为此时 3个 goroutine读锁定还未进行读解锁操作
- 当 3个 goroutine读解锁完成后,main函数写锁定才会完成
RWMutexMutexRWMutexMutex
输出
sync.LockerMutexRWMutex
技术文章持续更新,请大家多多关注呀~~
搜索微信公众号,关注我【 帽儿山的枪手 】
参考材料
[1] "《Go并发编程实战》书籍"
[2]: "《Concurrency in Go》书籍"
[3] sync标准库