Golang

Golang

go协程工具WaitGroup

go协程工具WaitGroup waitGroup 是go语言非常常用的一个协程的流程工具,可以在指定位置阻塞等待指定数量的协程执行完成,从字面意思理解即是阻塞等待指定组的协程执行完成,在需要控制或者等待一批协程执行完成时可以使用waitGroup 实现该效果,其实该包的原理也是使用了channel实现的协程同步机制,通过在指定位置添加waitGroup.Wait() 方法来阻塞等待指定数量的协程执行完成,在协程执行完成后调用waitGroup.Done() 方法来通知waitGroup 协程执行完成,waitGroup 内部维护了一个计数器,当计数器为0时,waitGroup.Wait() 方法才会返回,否则会阻塞等待。 type WaitGroup struct { } func (wg WaitGroup) Add(delta int) func (wg WaitGroup) Done() func (wg WaitGroup) Wait() Add(delta int) 每次激活想要被等待完成的协程之前,先调用Add(),用来设置或添加要等待完成的goroutine数量 Done() 表示该协程执行完成,执行Done()会将waitGroup 内部的计数器减1 Wait() 表示等待所有的协程执行完成,当waitGroup 内部的计数器为0时,Wait() 方法才会返回,否则会阻塞等待 一般在所有的协程执行完成后调用Wait() 方法,等待所有的协程执行完成 func (wg WaitGroup) Add(delta int) { // 先从 state 当中把数据和信号量取出来 statep, semap := wg.state() // 在 […]

Golang

Go语言syncMap实现的功能和使用场景

Go语言syncMap实现的功能和使用场景 在go语言提供的标准map类型中,如果涉及到协程读取map的场景,会存在并发读写的问题,并发操作map的会导致数据不一致, 为什么map不是并发安全的? 因为map的读写操作不是原子操作,当多个协程同时读写map时,会发生脏读和脏写导致数据不一致的问题。 在go 语言1.9版本后引入了syncMap,可以提供更加便捷的并发map操作方法, 例如: var m sync.Map 可以使用syncMap的方法来进行并发安全的map操作,例如: m.Store(key, value) m.Load(key) m.Delete(key) 这些方法都是并发安全的,不会导致数据不一致的问题。 但是该数据类型仅适合一定程度上的读多写少场景,syncMap内部使用了读写锁来实现并发安全,当写操作比较多时,会导致读操作的阻塞,影响性能。 源码:https://github.com/golang/go/blob/go1.23.0/src/sync/map.go func (m *Map) Swap(key, value any) (previous any, loaded bool) { read := m.loadReadOnly() if e, ok := read.m[key]; ok { if v, ok := e.trySwap(&value); ok { if v == nil { return nil, false }

Scroll to Top