go 锁的使用

作者: 吃猫的鱼0 | 来源:发表于2018-01-04 11:08 被阅读7次

    互斥锁

       由标准库代码包sync中的Mutex结构体类型代表,sync.Mutex类型(确切地说,是*sync.Mutex类型)只有两个公开方法——Lock和Unlock。顾名思义,前者被用于锁定当前的互斥量,而后者则被用来对当前的互斥量进行解锁。

    package main
    
    import (
        "sync"
        "fmt"
        "runtime"
        "time"
    )
    type Accout struct {
        flag sync.Mutex         //sync.Mutex类型
        money int
    }
    //进行买的操作
    func (a *Accout) Buy(n int) {  //自己买的工资
        a.flag.Lock()           //锁上
        defer a.flag.Unlock()   //在方法运行完之后解开
        if a.money >n {
            a.Do_Prepare()
            a.money -= n
        }else {
            fmt.Println("您自己买的余额已不足!请及时充值~")
        }
    }
    //交易操作
    func (a *Accout) Do_Prepare()  {
        fmt.Println("您的余额充足可以进行交易")
    }
    //工资添加
    func (a *Accout) Add_Money(m int)  {
        a.flag.Lock()           //锁上
        defer a.flag.Unlock()   //在方法运行完之后解开
        a.money+=m
        fmt.Println("添加money",m)
    }
    func main() {
        runtime.GOMAXPROCS(runtime.NumCPU())
        aa:=Accout{*new(sync.Mutex),100}
        for i:=0; i<5;i++  {
            go aa.Buy(50)
            go aa.Add_Money(20)
        }
        time.Sleep(time.Millisecond)
    }
    

    读写锁

       读写锁由结构体类型sync.RWMutex代表。它可以分别针对读操作和写操作进行锁定和解锁操作。

    • 注:

       1、多个读之间不存在互斥关系

       2、写操作之间都是互斥的,并且写操作与读操作之间也都是互斥的

    读===》

    var m *sync.RWMutex  //定义m的类型为读写锁。
    m.RLock()  //读锁定
    m.RUnlock() //读解锁
    

    读的时候随便读

    package main
    
    import (
        "sync"
        "time"
    )
    
    var m *sync.RWMutex
    
    func main() {
        m = new(sync.RWMutex)
        
        // 多个同时读
        go read(1)
        go read(2)
    
        time.Sleep(2*time.Second)
    }
    
    func read(i int) {
        println(i,"read start")
    
        m.RLock()
        println(i,"reading")
        time.Sleep(1*time.Second)
        m.RUnlock()    
    
        println(i,"read over")
    }
    

    写===》

    var m *sync.RWMutex  //定义m的类型为读写锁。
    m.Lock() //写操作锁定
    m.Unlock()  //写操作解锁
    

    写的时候啥也不能做

    package main
    
    import (
        "sync"
        "time"
    )
    
    var m *sync.RWMutex
    
    func main() {
        m = new(sync.RWMutex)
        
        // 写的时候啥也不能干
        go write(1)
        go read(2)
        go write(3)
    
        time.Sleep(2*time.Second)
    }
    
    func read(i int) {
        println(i,"read start")
    
        m.RLock()
        println(i,"reading")
        time.Sleep(1*time.Second)
        m.RUnlock()    
    
        println(i,"read over")
    }
    
    func write(i int) {
        println(i,"write start")
    
        m.Lock()
        println(i,"writing")
        time.Sleep(1*time.Second)
        m.Unlock()
    
        println(i,"write over")
    }
    

    wait group

       WaitGroup在go语言中,用于线程同步,它能够一直等到所有的goroutine执行完成,并且阻塞主线程的执行,直到所有的goroutine执行完成。

      

    阻塞主线程等goroutine执行完之后再放开
    

    定义:
    wg := new(sync.WaitGroup) //定义一个WaitGroup,就是用来等待都
    添加几个协程:
    wg.Add(2) //有几个进程需要等待就写几个,写多或写少都会报错哟~
    运行某个协程:
        go func() {
            wg.Done() //该进程结束就发送结束标志。
        }()
    标记所有协程执行完毕
    wg.Wait()  //等待所有协程结束后在执行以下都代码。

    相关文章

      网友评论

        本文标题:go 锁的使用

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