golang部分的锁,主要在sync包里
runtime/sema(信号量)
runtime中的sema.go,信号量的同步功能是作用于goroutine的
1 | type semaRoot struct { |
golang设置了可操作信号量个数的最大量是251,相关操作,还是看链表的操作
sync/atomic
这里原子操作,是保证多个cpu(协程)对同一块内存区域的操作是原子的
1 | // 互斥量加锁操作 |
sync/mutex(互斥锁)
sync/mutex.go
1 | // A Mutex must not be copied after first use. |
lock流程
简单来说,如果当前goroutine可以加锁,那么调用原子操作使得mutex中的flag设置成已占用达到互斥;如果当前goroutine发现锁已被占用,那么会有条件的循环尝试获取锁,这里是不用信号量去对goroutine进行sleep和wake操作的(尽可能避免开销),如果循环尝试失败,则最后调用原子操作争抢一次,获取不到则还是得调用runtime_Semacquire去判断阻塞goroutine还是继续争用锁。
sync/RWMutex(读写锁)
1 | type RWMutex struct { |
写锁定
1 | func (rw *RWMutex) Lock() { |