内存锁模块,也称之为 动态互斥锁 模块,支持按照 给定键名动态生成互斥锁,并发安全并支持 Try*Lock 特性。

当维护大量动态互斥锁的场景时,如果不再使用的互斥锁对象,请手动调用 Remove 方法删除掉。

使用方式

  1. import "github.com/gogf/gf/v2/os/gmlock"

使用场景: 需要 动态创建互斥锁,或者需要 维护大量动态锁 的场景;

接口文档

https://pkg.go.dev/github.com/gogf/gf/v2/os/gmlock

  1. func Lock(key string)
  2. func LockFunc(key string, f func())
  3. func RLock(key string)
  4. func RLockFunc(key string, f func())
  5. func RUnlock(key string)
  6. func Remove(key string)
  7. func TryLock(key string) bool
  8. func TryLockFunc(key string, f func()) bool
  9. func TryRLock(key string) bool
  10. func TryRLockFunc(key string, f func()) bool
  11. func Unlock(key string)
  12. type Locker
  13. func New() *Locker
  14. func (l *Locker) Clear()
  15. func (l *Locker) Lock(key string)
  16. func (l *Locker) LockFunc(key string, f func())
  17. func (l *Locker) RLock(key string)
  18. func (l *Locker) RLockFunc(key string, f func())
  19. func (l *Locker) RUnlock(key string)
  20. func (l *Locker) Remove(key string)
  21. func (l *Locker) TryLock(key string) bool
  22. func (l *Locker) TryLockFunc(key string, f func()) bool
  23. func (l *Locker) TryRLock(key string) bool
  24. func (l *Locker) TryRLockFunc(key string, f func()) bool
  25. func (l *Locker) Unlock(key string)

示例1,基本使用

  1. package main
  2. import (
  3. "time"
  4. "sync"
  5. "github.com/gogf/gf/v2/os/glog"
  6. "github.com/gogf/gf/v2/os/gmlock"
  7. )
  8. func main() {
  9. key := "lock"
  10. wg := sync.WaitGroup{}
  11. for i := 0; i < 10; i++ {
  12. wg.Add(1)
  13. go func(i int) {
  14. gmlock.Lock(key)
  15. glog.Println(i)
  16. time.Sleep(time.Second)
  17. gmlock.Unlock(key)
  18. wg.Done()
  19. }(i)
  20. }
  21. wg.Wait()
  22. }

该示例中,模拟了同时开启 10goroutine,但同一时刻只能有一个 goroutine 获得锁,获得锁的 goroutine 执行 1 秒后退出,其他 goroutine 才能获得锁。

执行后,输出结果为:

  1. 2018-10-15 23:57:28.295 9
  2. 2018-10-15 23:57:29.296 0
  3. 2018-10-15 23:57:30.296 1
  4. 2018-10-15 23:57:31.296 2
  5. 2018-10-15 23:57:32.296 3
  6. 2018-10-15 23:57:33.297 4
  7. 2018-10-15 23:57:34.297 5
  8. 2018-10-15 23:57:35.297 6
  9. 2018-10-15 23:57:36.298 7
  10. 2018-10-15 23:57:37.298 8

示例2,TryLock非阻塞锁

TryLock 方法是有返回值的,它表示用来尝试获取锁,如果获取成功,则返回 true;如果获取失败(即互斥锁已被其他 goroutine 获取),则返回 false

  1. package main
  2. import (
  3. "sync"
  4. "github.com/gogf/gf/v2/os/glog"
  5. "time"
  6. "github.com/gogf/gf/v2/os/gmlock"
  7. )
  8. func main() {
  9. key := "lock"
  10. wg := sync.WaitGroup{}
  11. for i := 0; i < 10; i++ {
  12. wg.Add(1)
  13. go func(i int) {
  14. if gmlock.TryLock(key) {
  15. glog.Println(i)
  16. time.Sleep(time.Second)
  17. gmlock.Unlock(key)
  18. } else {
  19. glog.Println(false)
  20. }
  21. wg.Done()
  22. }(i)
  23. }
  24. wg.Wait()
  25. }

同理,在该示例中,同时也只有 1goroutine 能获得锁,其他 goroutineTryLock 失败便直接退出了。

执行后,输出结果为:

  1. 2018-10-16 00:01:59.172 9
  2. 2018-10-16 00:01:59.172 false
  3. 2018-10-16 00:01:59.172 false
  4. 2018-10-16 00:01:59.172 false
  5. 2018-10-16 00:01:59.172 false
  6. 2018-10-16 00:01:59.172 false
  7. 2018-10-16 00:01:59.172 false
  8. 2018-10-16 00:01:59.172 false
  9. 2018-10-16 00:01:59.172 false
  10. 2018-10-16 00:01:59.176 false