gf 프레임 의 gmlock - 메모리 잠 금 모듈

글 의 출처:http://gf.johng.cn/os/gmlock/...
메모리 자물쇠.이 모듈 은 두 개의 대상 특성 을 포함 합 니 다:
  • Locker 메모리 잠 금 은 에 따라 지원 하고 Try*Lock 특성 을 지원 합 니 다.
  • Mutex 표준 창고 밑바닥 sync.Mutex 에 대한 포장 은 Try*Lock 특성 을 증가 시 켰 다.

  • 사용 방법:
    import "gitee.com/johng/gf/g/os/gmlock"

    사용 필드:
  • 안전 을 병행 해 야 하 는 모든 장면 은 대체 할 수 있다 sync.Mutex.
  • 사용 해 야 하 는 장면 Try*Lock.
  • 필요 또는 필요 한 장면;

  • 방법 목록
    func Lock(key string, expire ...int)
    func RLock(key string, expire ...int)
    func RUnlock(key string)
    func TryLock(key string, expire ...int) bool
    func TryRLock(key string, expire ...int) bool
    func Unlock(key string)
    type Locker
        func New() *Locker
        func (l *Locker) Lock(key string, expire ...int)
        func (l *Locker) RLock(key string, expire ...int)
        func (l *Locker) RUnlock(key string)
        func (l *Locker) TryLock(key string, expire ...int) bool
        func (l *Locker) TryRLock(key string, expire ...int) bool
        func (l *Locker) Unlock(key string)
    type Mutex
        func NewMutex() *Mutex
        func (l *Mutex) Lock()
        func (l *Mutex) RLock()
        func (l *Mutex) RUnlock()
        func (l *Mutex) TryLock() bool
        func (l *Mutex) TryRLock() bool
        func (l *Mutex) Unlock()

    예시 1, 기본 사용
    package main
    
    import (
        "time"
        "sync"
        "gitee.com/johng/gf/g/os/glog"
        "gitee.com/johng/gf/g/os/gmlock"
    )
    
    func main() {
        key := "lock"
        wg  := sync.WaitGroup{}
        for i := 0; i < 10; i++ {
            wg.Add(1)
            go func(i int) {
                gmlock.Lock(key)
                glog.Println(i)
                time.Sleep(time.Second)
                gmlock.Unlock(key)
                wg.Done()
            }(i)
        }
        wg.Wait()
    }

    이 예제 에 서 는 goroutine 10 개 를 동시에 여 는 것 을 모 의 했 으 나 같은 시간 에 하나의 goroutine 만 자 물 쇠 를 얻 을 수 있 고 자 물 쇠 를 얻 은 goroutine 은 1 초 후에 종료 해 야 다른 goroutine 이 자 물 쇠 를 얻 을 수 있 습 니 다.
    실행 후 출력 결 과 는:
    2018-10-15 23:57:28.295 9
    2018-10-15 23:57:29.296 0
    2018-10-15 23:57:30.296 1
    2018-10-15 23:57:31.296 2
    2018-10-15 23:57:32.296 3
    2018-10-15 23:57:33.297 4
    2018-10-15 23:57:34.297 5
    2018-10-15 23:57:35.297 6
    2018-10-15 23:57:36.298 7
    2018-10-15 23:57:37.298 8

    예제 2, 만 료 제어
    우 리 는 이상 의 예 시 를 기한 이 지난 시간 통 제 를 사용 하여 실현 할 것 이다.
    package main
    
    import (
        "sync"
        "gitee.com/johng/gf/g/os/glog"
        "gitee.com/johng/gf/g/os/gmlock"
    )
    
    func main() {
        key := "lock"
        wg  := sync.WaitGroup{}
        for i := 0; i < 10; i++ {
            wg.Add(1)
            go func(i int) {
                gmlock.Lock(key, 1000)
                glog.Println(i)
                wg.Done()
            }(i)
        }
        wg.Wait()
    }

    실행 후 출력 결 과 는:
    2018-10-15 23:59:14.663 9
    2018-10-15 23:59:15.663 4
    2018-10-15 23:59:16.663 0
    2018-10-15 23:59:17.664 1
    2018-10-15 23:59:18.664 2
    2018-10-15 23:59:19.664 3
    2018-10-15 23:59:20.664 6
    2018-10-15 23:59:21.664 5
    2018-10-15 23:59:22.665 7
    2018-10-15 23:59:23.665 8

    예제 3, TryLock 비 차단 잠 금TryLock 방법 은 반환 값 이 있 습 니 다. 자 물 쇠 를 가 져 오 려 고 시도 하고 성공 하면 되 돌려 줍 니 다 true.가 져 오 는 데 실 패 했 을 경우 (즉, 잠 금 이 다른 goroutine 에 의 해 가 져 왔 음) 되 돌아 갑 니 다 false.
    package main
    
    import (
        "sync"
        "gitee.com/johng/gf/g/os/glog"
        "time"
        "gitee.com/johng/gf/g/os/gmlock"
    )
    
    func main() {
        key := "lock"
        wg  := sync.WaitGroup{}
        for i := 0; i < 10; i++ {
            wg.Add(1)
            go func(i int) {
                if gmlock.TryLock(key) {
                    glog.Println(i)
                    time.Sleep(time.Second)
                    gmlock.Unlock(key)
                } else {
                    glog.Println(false)
                }
                wg.Done()
            }(i)
        }
        wg.Wait()
    }

    마찬가지 로 이 예제 에서 1 개의 goroutine 만 자 물 쇠 를 얻 을 수 있 고 다른 goroutine 은 TryLock 에서 실패 하면 바로 탈퇴 합 니 다.
    실행 후 출력 결 과 는:
    2018-10-16 00:01:59.172 9
    2018-10-16 00:01:59.172 false
    2018-10-16 00:01:59.172 false
    2018-10-16 00:01:59.172 false
    2018-10-16 00:01:59.172 false
    2018-10-16 00:01:59.172 false
    2018-10-16 00:01:59.172 false
    2018-10-16 00:01:59.172 false
    2018-10-16 00:01:59.172 false
    2018-10-16 00:01:59.176 false

    예시 4, 여러 개의 자물쇠 메커니즘 충돌
    이 예 는 복잡 한 논리 에서 의 잠 금 메커니즘 처리 상황 을 보 여 주 는 데 쓰 인 다.
    package main
    
    import (
        "gitee.com/johng/gf/g/os/gmlock"
        "time"
        "gitee.com/johng/gf/g/os/glog"
        "fmt"
    )
    
    //     -   Unlock   Unlock    
    func main() {
        key := "key"
    
        //        
        gmlock.Lock(key, 1000)
        glog.Println("lock1")
        //                
        gmlock.Unlock(key)
        glog.Println("unlock1")
    
        fmt.Println()
    
        //     ,    ,          Lock       
        gmlock.Lock(key)
        glog.Println("lock2")
        go func() {
            //      3        
            gmlock.Lock(key)
            glog.Println("lock by goroutine")
        }()
        time.Sleep(3*time.Second)
        //      
        gmlock.Unlock(key)
        //   3          
        glog.Println("unlock2")
    
        //     
        select{}
    }

    실행 후 출력 결 과 는:
    2018-10-16 00:03:40.277 lock1
    2018-10-16 00:03:40.279 unlock1
    
    2018-10-16 00:03:40.279 lock2
    2018-10-16 00:03:43.279 unlock2
    2018-10-16 00:03:43.279 lock by goroutine

    예제 5, 다 중 파일 동시 작성 보안 제어glog 모듈 에서 로그 파일 을 쓸 때 이러한 핵심 방법 이 있 습 니 다. (소스 코드 는 / g / os / glog / glog logger. go 에 있 습 니 다)
    //                    ,        
    func (l *Logger) print(std io.Writer, s string) {
        //         IO  
        if l.printHeader.Val() {
            s = l.format(s)
        }
        writer := l.GetWriter()
        if writer == nil {
            //      writer  ,               
            //         ,   glog                   (    )
            if f := l.getFilePointer(); f != nil {
                defer f.Close()
                key := l.path.Val()
                gmlock.Lock(key)
                _, err := io.WriteString(f, s)
                gmlock.Unlock(key)
                if err != nil {
                    fmt.Fprintln(os.Stderr, err.Error())
                }
            }
        } else {
            l.doStdLockPrint(writer, s)
        }
        //            
        if l.alsoStdPrint.Val() {
            l.doStdLockPrint(std, s)
        }
    }

    그 중의:
    gmlock.Lock(key)
    ...
    gmlock.Unlock(key)

    메모리 잠 금 의 특성 을 사 용 했 습 니 다. 그 중의 변수 key 는 로그 파일 을 표시 합 니 다. 여러 개의 goroutine 이 같은 로그 파일 을 기록 할 때 gmlock.Lock(key) 에서 이 파일 의 동시 다발 안전 쓰기 작업 을 보장 합 니 다.

    좋은 웹페이지 즐겨찾기