The memory lock module, also known as the dynamic mutex lock module, supports dynamically generating mutex locks based on given key names, ensuring concurrency safety and supporting the Try*Lock feature.

In scenarios where a large number of dynamic mutex locks are maintained, please manually call the Remove method to delete mutex lock objects that are no longer in use.

Usage:

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

Usage scenarios: Scenarios that require dynamic creation of mutex locks, or need to maintain a large number of dynamic locks;

Interface documentation:

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)

Example 1: Basic Usage

  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. }

In this example, it simulates opening 10 goroutines simultaneously, but at any one time only one goroutine can acquire the lock. The goroutine with the lock will execute for 1 second before exiting, allowing other goroutines to acquire the lock.

After execution, the output is:

  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

Example 2: TryLock Non-blocking Lock

The TryLock method returns a value, indicating whether the lock was successfully acquired. If successful, it returns true; if the lock is already acquired by another goroutine, it returns 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. }

Similarly, in this example, only 1 goroutine can acquire the lock at the same time, and other goroutines will exit immediately if TryLock fails.

After execution, the output is:

  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