当前位置:首页 > 科技  > 软件

使用 sync.Cond 来协调并发 goroutine 的访问共享资源

来源: 责编: 时间:2023-11-28 09:33:25 364观看
导读使用 sync.Cond 解决并发访问共享资源问题在并发编程中,当多个 goroutine 需要访问共享资源时,我们需要使用一些机制来协调它们的执行顺序,以避免竞态条件和数据不一致的问题。在 Go 语言中,sync.Cond 条件变量就是一种常

使用 sync.Cond 解决并发访问共享资源问题

在并发编程中,当多个 goroutine 需要访问共享资源时,我们需要使用一些机制来协调它们的执行顺序,以避免竞态条件和数据不一致的问题。在 Go 语言中,sync.Cond 条件变量就是一种常用的机制,它可以用来等待和通知其他 goroutine。Zgr28资讯网——每日最新资讯28at.com

sync.Cond 和互斥锁的区别

互斥锁(sync.Mutex)用于保护临界区和共享资源,而 sync.Cond 则用于协调多个 goroutine 的执行顺序。互斥锁只能一个 goroutine 持有锁,其他 goroutine 必须等待锁被释放才能继续执行。而 sync.Cond 可以让等待的 goroutine 在条件满足时被唤醒,进而继续执行。Zgr28资讯网——每日最新资讯28at.com

sync.Cond 的四个方法

sync.Cond 的定义如下:Zgr28资讯网——每日最新资讯28at.com

// Each Cond has an associated Locker L (often a *Mutex or *RWMutex),// which must be held when changing the condition and// when calling the Wait method.//// A Cond must not be copied after first use.type Cond struct {        noCopy noCopy        // L is held while observing or changing the condition        L Locker        notify  notifyList        checker copyChecker}

每个 Cond 实例都会关联一个锁 L(互斥锁 *Mutex,或读写锁 *RWMutex),当修改条件或者调用 Wait 方法时,必须加锁。Zgr28资讯网——每日最新资讯28at.com

1. NewCond 创建实例

func NewCond(l Locker) *Cond

NewCond 方法用于创建一个 Cond 实例,并关联一个锁(互斥锁或读写锁)。Zgr28资讯网——每日最新资讯28at.com

2. Broadcast 广播唤醒所有等待的 goroutine

// Broadcast wakes all goroutines waiting on c.//// It is allowed but not required for the caller to hold c.L// during the call.func (c *Cond) Broadcast()

Broadcast 方法用于唤醒所有等待条件变量 c 的 goroutine。它不需要持有锁来调用。Zgr28资讯网——每日最新资讯28at.com

3. Signal 唤醒一个等待的 goroutine

// Signal wakes one goroutine waiting on c, if there is any.//// It is allowed but not required for the caller to hold c.L// during the call.func (c *Cond) Signal()

Signal 方法用于唤醒一个等待条件变量 c 的 goroutine。它不需要持有锁来调用。Zgr28资讯网——每日最新资讯28at.com

4. Wait 等待条件变量满足

// Wait atomically unlocks c.L and suspends execution// of the calling goroutine. After later resuming execution,// Wait locks c.L before returning. Unlike in other systems,// Wait cannot return unless awoken by Broadcast or Signal.//// Because c.L is not locked when Wait first resumes, the caller// typically cannot assume that the condition is true when// Wait returns. Instead, the caller should Wait in a loop:////    c.L.Lock()//    for !condition() {//        c.Wait()//    }//    ... make use of condition ...//    c.L.Unlock()//func (c *Cond) Wait()

Wait 方法会自动释放锁,并挂起当前的 goroutine,直到条件变量 c 被 Broadcast 或 Signal 唤醒。被唤醒后,Wait 方法会重新获得锁,并继续执行后续的代码。Zgr28资讯网——每日最新资讯28at.com

使用示例

下面是一个使用 sync.Cond 的示例,实现了一个简单的读写同步机制:Zgr28资讯网——每日最新资讯28at.com

package mainimport (    "fmt"    "sync"    "time")var done = falsefunc read(str string, c *sync.Cond) {    c.L.Lock()    for !done {        c.Wait()    }    fmt.Println(str, "start reading")    c.L.Unlock()}func write(str string, c *sync.Cond) {    fmt.Println(str, "start writing")    time.Sleep(2 * time.Second)    c.L.Lock()    done = true    c.L.Unlock()    fmt.Println(str, "wake up all")    c.Broadcast()}func main() {    m := &sync.Mutex{}    c := sync.NewCond(m)    go read("reader1", c)    go read("reader2", c)    write("writer", c)    time.Sleep(5 * time.Second)}

在这个示例中,有两个读取协程(reader1 和 reader2)和一个写入协程(writer)。写入协程在执行后会通知所有等待的读取协程,读取协程在条件满足时才能开始读取。Zgr28资讯网——每日最新资讯28at.com

输出结果如下:Zgr28资讯网——每日最新资讯28at.com

writer start writingwriter wake up allreader2 start readingreader1 start reading

通过使用 sync.Cond,我们可以很方便地实现多个 goroutine 之间的等待和通知机制,从而更好地协调并发访问共享资源的执行顺序。Zgr28资讯网——每日最新资讯28at.com

本文链接:http://www.28at.com/showinfo-26-34582-0.html使用 sync.Cond 来协调并发 goroutine 的访问共享资源

声明:本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。邮件:2376512515@qq.com

上一篇: 如何高效地使用Goroutine,你学会了?

下一篇: Spring到底是如何解决循环依赖问题的?​

标签:
  • 热门焦点
  • 19个 JavaScript 单行代码技巧,让你看起来像个专业人士

    今天这篇文章跟大家分享18个JS单行代码,你只需花几分钟时间,即可帮助您了解一些您可能不知道的 JS 知识,如果您已经知道了,就当作复习一下,古人云,温故而知新嘛。现在,我们就开始今
  • Python异步IO编程的进程/线程通信实现

    这篇文章再讲3种方式,同时讲4中进程间通信的方式一、 Python 中线程间通信的实现方式共享变量共享变量是多个线程可以共同访问的变量。在Python中,可以使用threading模块中的L
  • 每天一道面试题-CPU伪共享

    前言:了不起:又到了每天一到面试题的时候了!学弟,最近学习的怎么样啊 了不起学弟:最近学习的还不错,每天都在学习,每天都在进步! 了不起:那你最近学习的什么呢? 了不起学弟:最近在学习C
  • 使用AIGC工具提升安全工作效率

    在日常工作中,安全人员可能会涉及各种各样的安全任务,包括但不限于:开发某些安全工具的插件,满足自己特定的安全需求;自定义github搜索工具,快速查找所需的安全资料、漏洞poc、exp
  • 猿辅导与新东方的两种“归途”

    作者|卓心月 出品|零态LT(ID:LingTai_LT)如何成为一家伟大企业?答案一定是对“势”的把握,这其中最关键的当属对企业战略的制定,且能够站在未来看现在,即使这其中的
  • 消息称小米汽车开始筛选交付中心:需至少120个车位

    IT之家 7 月 7 日消息,日前,有微博简介为“汽车行业从业者、长三角一体化拥护者”的微博用户 @长三角行健者 发文表示,据经销商集团反馈,小米汽车目前
  • iQOO Neo8系列今日官宣:首发天玑9200+ 全球安卓最强芯!

    在昨日举行的的联发科新一代旗舰芯片天玑9200+的发布会上,iQOO官方也正式宣布,全新的iQOO Neo8系列新品将全球首发搭载这款当前性能最强大的移动平台
  • Windows 11发布,微软一改往常对老机型开放的态度

    距离 Windows 11 发布已经过去一周,在过去一周里,很多数码爱好者围绕其对 Android 应用的支持、对老机型的升级问题展开了激烈讨论。与以往不同的是,在这次大
  • 利用职权私自解除被封帐号 Meta开除20多名员工

    11月18日消息,据外媒援引知情人士表示,过去一年时间内,Facebook母公司Meta解雇或处罚了20多名员工以及合同工,指控这些人通过内部系统以不当方式重置用户帐号,其
Top