Home > Backend Development > Golang > How to Avoid Race Conditions When Using sync.Cond for Conditional Waiting?

How to Avoid Race Conditions When Using sync.Cond for Conditional Waiting?

Susan Sarandon
Release: 2024-11-10 14:21:02
Original
926 people have browsed it

How to Avoid Race Conditions When Using sync.Cond for Conditional Waiting?

Correctly Using sync.Cond for Conditional Waiting

While exploring the functionality of sync.Cond, it became evident that a race condition could arise between locking the sync.Mutex and invoking cond.Wait. To demonstrate this, an artificial delay was introduced into the main goroutine, simulating the race condition:

package main

import (
    "sync"
    "time"
)

func main() {
    var m sync.Mutex
    var c = sync.NewCond(&m)

    go func() {
        time.Sleep(1 * time.Second)
        c.Broadcast()
    }()

    m.Lock()
    time.Sleep(2 * time.Second)
    c.Wait()
}
Copy after login

Executing this code results in a deadlock panic due to the goroutine waiting for a condition that has not been signaled yet.

Addressing the Race Condition

The correct approach to avoid this race condition is to ensure that the sync.Mutex is locked before calling cond.Wait. This prevents other goroutines from modifying the shared data while the current goroutine is waiting on a condition:

package main

import (
    "sync"
    "time"
)

func main() {
    var m sync.Mutex
    var c = sync.NewCond(&m)

    go func() {
        time.Sleep(1 * time.Second)
        m.Lock()
        c.Broadcast()
        m.Unlock()
    }()

    m.Lock()
    c.Wait()
    m.Unlock()
}
Copy after login

Alternative Synchronization Constructs

While sync.Cond can be useful in scenarios where multiple goroutines wait for a shared resource to become available, it is important to consider alternative synchronization primitives. For instance, if you have a one-to-one relationship between a writer and reader, a sync.Mutex may suffice for communication:

var sharedRsc = make(map[string]interface{})

func main() {
    m := sync.Mutex{}
    go func() {
        m.Lock()
        sharedRsc["rsc1"] = "foo"
        m.Unlock()
    }()

    m.Lock()
    fmt.Println(sharedRsc["rsc1"])
    m.Unlock()
}
Copy after login

In cases where multiple readers are involved, channels offer a more efficient and scalable solution for passing data around.

The above is the detailed content of How to Avoid Race Conditions When Using sync.Cond for Conditional Waiting?. For more information, please follow other related articles on the PHP Chinese website!

source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Latest Articles by Author
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template