首页 > 后端开发 > Golang > 使用sync.Cond进行条件等待时如何避免竞争条件?

使用sync.Cond进行条件等待时如何避免竞争条件?

Susan Sarandon
发布: 2024-11-10 14:21:02
原创
925 人浏览过

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

正确使用sync.Cond进行条件等待

在探索sync.Cond的功能时,很明显可能会出现竞争条件锁定sync.Mutex 和调用cond.Wait 之间。为了证明这一点,在主 Goroutine 中引入了人为延迟,模拟竞争条件:

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()
}
登录后复制

执行此代码会导致死锁恐慌,因为 goroutine 正在等待尚未发出信号的条件.

解决竞争条件

避免这种竞争条件的正确方法是确保在调用 cond.Wait 之前锁定sync.Mutex。这可以防止当前 Goroutine 在等待某个条件时其他 Goroutine 修改共享数据:

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()
}
登录后复制

替代同步构造

虽然sync.Cond 很有用在多个 goroutine 等待共享资源变得可用的情况下,考虑替代同步原语非常重要。例如,如果编写者和读者之间存在一对一的关系,则sync.Mutex可能足以进行通信:

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()
}
登录后复制

在涉及多个读者的情况下,通道提供了更有效的方式用于传递数据的可扩展解决方案。

以上是使用sync.Cond进行条件等待时如何避免竞争条件?的详细内容。更多信息请关注PHP中文网其他相关文章!

来源:php.cn
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
作者最新文章
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板