大家好,今天将梳理出的 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 使用

举例:读写锁的使用

输出

  1. 启用了 3 个 goroutine 用于读写锁 rwm 的读锁定和读解锁操作
  2. 读解锁操作会延迟 2s 进行模拟真是的情况
  3. 先让主 goroutine 睡眠 100ms,让 3个 goroutine先有足够时间执行
  4. 之后 rwm 的写锁定操作让主 goroutine 阻塞,因为此时 3个 goroutine读锁定还未进行读解锁操作
  5. 当 3个 goroutine读解锁完成后,main函数写锁定才会完成


RWMutexMutexRWMutexMutex

输出

sync.LockerMutexRWMutex


技术文章持续更新,请大家多多关注呀~~

搜索微信公众号,关注我【 帽儿山的枪手 】




参考材料

[1] "《Go并发编程实战》书籍"

[2]: "《Concurrency in Go》书籍"

[3] sync标准库