How to correctly use sync.Cond?

前端 未结 8 952
忘了有多久
忘了有多久 2021-02-01 16:11

I\'m having trouble figuring out how to correctly use sync.Cond. From what I can tell, a race condition exists between locking the Locker and invoking the condition\'s Wait meth

8条回答
  •  眼角桃花
    2021-02-01 17:13

    OP answered his own, but did not directly answer the original question, I am going to post how to correctly use sync.Cond.

    You do not really need sync.Cond if you have one goroutine for each write and read - a single sync.Mutex would suffice to communicate between them. sync.Cond could useful in situations where multiple readers wait for the shared resources to be available.

    var sharedRsc = make(map[string]interface{})
    func main() {
        var wg sync.WaitGroup
        wg.Add(2)
        m := sync.Mutex{}
        c := sync.NewCond(&m)
        go func() {
            // this go routine wait for changes to the sharedRsc
            c.L.Lock()
            for len(sharedRsc) == 0 {
                c.Wait()
            }
            fmt.Println(sharedRsc["rsc1"])
            c.L.Unlock()
            wg.Done()
        }()
    
        go func() {
            // this go routine wait for changes to the sharedRsc
            c.L.Lock()
            for len(sharedRsc) == 0 {
                c.Wait()
            }
            fmt.Println(sharedRsc["rsc2"])
            c.L.Unlock()
            wg.Done()
        }()
    
        // this one writes changes to sharedRsc
        c.L.Lock()
        sharedRsc["rsc1"] = "foo"
        sharedRsc["rsc2"] = "bar"
        c.Broadcast()
        c.L.Unlock()
        wg.Wait()
    }
    

    Playground

    Having said that, using channels is still the recommended way to pass data around if the situation permitting.

    Note: sync.WaitGroup here is only used to wait for the goroutines to complete their executions.

提交回复
热议问题