美文网首页
golang 互斥锁 sync.Mutex

golang 互斥锁 sync.Mutex

作者: 清晨的麦田 | 来源:发表于2019-06-26 19:34 被阅读0次

    一、介绍
    sync.Mutex为互斥锁(也叫全局锁),Lock()加锁,Unlock()解锁。

    二、场景
    适用于场景: 读写次数不确定的场景(读写次数没有明显区别),同时只能一个读或者写

    三、代码测试

    正确示范

    package main
    
    import (
        "fmt"
        "sync"
        "runtime"
    )
    
    func main() {
        runtime.GOMAXPROCS(runtime.NumCPU())
        for i := 0; i <= 100; i++ {
            wg.Add(1)
            go add(i)
    
        }
        wg.Wait()
    }
    
    var s = 1000
    var lock sync.Mutex
    var wg = &sync.WaitGroup{}
    
    func add(count int) {
        lock.Lock()
        fmt.Printf("加锁----第%d个携程\n", count)
        for i := 0; i < 4; i++ {
            s++
            fmt.Printf("j %d gorount %d \n", s, count)
        }
        fmt.Printf("解锁----第%d个携程\n", count)
        wg.Done()
        defer lock.Unlock()
    }
    
    

    运行命令:go run -race main.go 并未出现竞争

    go run -race te.go
    加锁----第0个携程
    j 1001 gorount 0 
    j 1002 gorount 0 
    j 1003 gorount 0 
    j 1004 gorount 0 
    解锁----第0个携程
    加锁----第1个携程
    j 1005 gorount 1 
    j 1006 gorount 1 
    j 1007 gorount 1 
    j 1008 gorount 1 
    解锁----第1个携程
    加锁----第2个携程
    j 1009 gorount 2 
    j 1010 gorount 2 
    j 1011 gorount 2 
    j 1012 gorount 2 
    解锁----第2个携程
    加锁----第3个携程
    j 1013 gorount 3 
    j 1014 gorount 3 
    j 1015 gorount 3 
    j 1016 gorount 3 
    解锁----第3个携程
    加锁----第4个携程
    j 1017 gorount 4 
    j 1018 gorount 4 
    j 1019 gorount 4 
    j 1020 gorount 4 
    解锁----第4个携程
    加锁----第5个携程
    j 1021 gorount 5 
    j 1022 gorount 5 
    j 1023 gorount 5 
    j 1024 gorount 5 
    解锁----第5个携程
    
    

    错误示范
    此处注释掉互斥锁,增多协程数量为100

    package main
    
    import (
    "fmt"
    "sync"
    "runtime"
    )
    
    func main() {
        runtime.GOMAXPROCS(runtime.NumCPU())
        for i := 0; i <= 100; i++ {
            wg.Add(1)
            go add(i)
    
        }
        wg.Wait()
    }
    
    var s = 1000
    var lock sync.Mutex
    var wg = &sync.WaitGroup{}
    
    func add(count int) {
        //lock.Lock()
        fmt.Printf("加锁----第%d个携程\n", count)
        for i := 0; i < 4; i++ {
            s++
            fmt.Printf("j %d gorount %d \n", s, count)
        }
        fmt.Printf("解锁----第%d个携程\n", count)
        wg.Done()
        //defer lock.Unlock()
    }
    
    

    运行命令:go run -race main.go 出现竞争

    解锁----第53个携程
    ==================
    WARNING: DATA RACE
    Read at 0x0000011e04b0 by goroutine 48:
      main.add()
          /Users/lee/goworkspace/src/th/mutex/main.go:27 +0xc9
    
    Previous write at 0x0000011e04b0 by goroutine 54:
      main.add()
          /Users/lee/goworkspace/src/th/mutex/main.go:27 +0xe5
    
    Goroutine 48 (running) created at:
      main.main()
          /Users/lee/goworkspace/src/th/mutex/main.go:13 +0x8c
    
    Goroutine 54 (running) created at:
    
    

    排解方法:
    通过上述结果可以看出竞争出现的错误位置,方便我们去解决此类问题

    相关文章

      网友评论

          本文标题:golang 互斥锁 sync.Mutex

          本文链接:https://www.haomeiwen.com/subject/rkyhcctx.html