Go基础补充 | 青训营笔记

60 阅读2分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第 2 天

互斥锁Mutex:底层原理:定义了type Mutex struct {state int32 sema uint32}数据结构,state是32位的,Locked(表示该Mutex是否已被锁定)/Woken(表示是否有协程已被唤醒)/Starving(表示该Mutex是否处理饥饿状态)/Waiter(表示阻塞等待锁的协程个数)

自旋:定义:当一个协程占用了锁,另一个协程尝试加锁,它不会立刻进入到等待队列,而是继续探测该锁Locked是否为0。一般自旋4次还没获取锁就进入到阻塞队列。

Go的抢锁模式:正常模式(不公平)G1持有锁,G2尝试加锁然后自旋4次进入阻塞队列,新进来的G3因为拥有CPU所以比之前的G2更容易获取锁,所以不公平。饥饿模式(公平)从模式下,直接将释放的锁交给阻塞队列的队首,新进来的G不参加竞争。

读写互斥锁RWMutex:定义:基于Mutex实现的,RWMutex适合读多写少的场景,可以多个G同时读取。

Go并发编程

Go的并发模型:共享内存模式(共享内存+锁实现) CSP模型(类似消息队列)(goroutine+channel实现)

Go有哪些方式安全读写共享变量?sync.Once/channel(通过通信来共享变量)/Mutex和RWMutex锁机制

sync.WaitGroup

Go语言中可以使用sync.WaitGroup来实现并发任务的同步。sync.WaitGroup内部维护着一个计数器,计数器的值可以增加和减少。例如当我们启动了 N 个并发任务时,就将计数器值增加N。每个任务完成时通过调用 Done 方法将计数器减1。通过调用 Wait 来等待并发任务执行完,当计数器值为 0 时,表示所有并发任务已经完成。

sync.Once

在某些场景下我们需要确保某些操作即使在高并发的场景下也只会被执行一次,例如只加载一次配置文件等。

Go语言中的sync包中提供了一个针对只执行一次场景的解决方案——sync.Once,sync.Once只有一个Do方法

总结

关于测试和gin看看李文周的博客,写的挺好,适合小白。