登录
首页 >  Golang >  Go问答

如何 100% 确定 goroutine 是按条件等待的?

来源:stackoverflow

时间:2024-04-10 19:36:32 168浏览 收藏

偷偷努力,悄无声息地变强,然后惊艳所有人!哈哈,小伙伴们又来学习啦~今天我将给大家介绍《如何 100% 确定 goroutine 是按条件等待的?》,这篇文章主要会讲到等等知识点,不知道大家对其都有多少了解,下面我们就一起来看一吧!当然,非常希望大家能多多评论,给出合理的建议,我们一起学习,一起进步!

问题内容

阅读 katherine cox-buday 撰写的《concurrency in go》一书,其中有如何使用 condition.broadcast 唤醒等待的 goroutine 的示例。这是书中的示例

package main

import (
    "fmt"
    "sync"
)

type Button struct {
    Clicked *sync.Cond
}

func main() {
    button := &Button{Clicked: &sync.Cond{L: &sync.Mutex{}}}

    subscribe := func(c *sync.Cond, fn func()) {
        var goroutineRunning sync.WaitGroup
        goroutineRunning.Add(1)
        go func() {
            goroutineRunning.Done() //1
            c.L.Lock()
            // 2
            defer c.L.Unlock()
            c.Wait()
            fn()
        }()
        goroutineRunning.Wait()
    }

    var clickedRegistred sync.WaitGroup
    clickedRegistred.Add(2)

    subscribe(button.Clicked, func() {
        fmt.Println("Func #1")
        clickedRegistred.Done()
    })

    subscribe(button.Clicked, func() {
        fmt.Println("Func #2")
        clickedRegistred.Done()
    })

    button.Clicked.Broadcast()
    clickedRegistred.Wait()
}

代码100%并发安全吗?

是否有可能出现这样的情况:主 goroutine 继续工作并在 func goroutine 停放并等待条件信号/广播之前进行广播?

我的意思是 func goroutine 在 //1 行完成工作但尚未获取条件锁并且 main goroutine 这次进行广播的情况,有可能吗?

我的假设如下:是否应该将行 //1 移动到位置 //2 以避免这种情况?

或者没有问题并且我描述的情况没有意义?


正确答案


我认为你的问题有两个部分:

  1. 此代码是否存在潜在的竞争错误?是:参见,例如,How do I know that all my goroutines are indeed waiting for a condition using golang's sync package

  2. 移动 done 调用是否可以修复?在这个特定的代码中,是的,但我想说,也许不是一个特别好的修复。如 his own answer 上的 Andy Schweig notes in a comment,使用条件的 wait 方法进行循环的代码更为典型:

    for some_boolean { c.Wait() }

    调用 c.signalc.broadcast 的代码会在调用 signalbroadcast 之前适当设置布尔值(此处为 false),以指示服务员现在应该停止等待。

今天关于《如何 100% 确定 goroutine 是按条件等待的?》的内容介绍就到此结束,如果有什么疑问或者建议,可以在golang学习网公众号下多多回复交流;文中若有不正之处,也希望回复留言以告知!

声明:本文转载于:stackoverflow 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>