为了账号安全,请及时绑定邮箱和手机立即绑定

我应该使用同步通道还是阻塞通道?

我应该使用同步通道还是阻塞通道?

Go
翻阅古今 2021-11-08 14:42:10
我有几个 go 例程,我使用无缓冲通道作为同步机制。我想知道这是否有什么问题(例如与 WaitGroup 实现相比)。我知道的一个已知“缺点”是,两个 go 例程可能会一直阻塞,直到第 3 个(最后一个)完成,因为通道没有缓冲,但我不知道内部结构/这真正意味着什么。func main() {    chan1, chan2, chan3 := make(chan bool), make(chan bool), make(chan bool)    go fn(chan1)    go fn(chan2)    go fn(chan3)    res1, res2, res3 := <-chan1, <-chan2, <-chan3}
查看完整描述

2 回答

?
一只萌萌小番薯

TA贡献1795条经验 获得超7个赞

这种实现本身并没有更糟或更好,我已经编写了这种风格的代码,以支持WaitGroup成功使用 a 。我也实现了相同的功能,WaitGroup并得到了大致相同的结果。正如评论中提到的,哪个更好是情境化的,并且在许多情况下可能是主观的(区别在于可维护性或可读性而不是性能)。

就我个人而言,我真的很喜欢这种风格,因为我要为一个系列中的每个项目分拆一名工人。我已经在干净地关闭时遇到了很多痛苦(在必须以一种或另一种方式提供给工作方法的中止或关闭通道上发出信号)所以我认为将通信循环更进一步是非常方便的并将所有作品包含在一个频道选择中。为了有一个工作中止,你无论如何都必须这样做。


查看完整回答
反对 回复 2021-11-08
?
尚方宝剑之说

TA贡献1788条经验 获得超4个赞

Channels 和WaitGroups 都可供您酌情使用。对于给定的问题,您的解决方案可以使用渠道WaitGroup或什至两者的组合来解决。


据我了解,当您的 goroutine 需要相互通信时,通道更合适(因为它们不是独立的)。WaitGroup通常在您的 goroutine 相互独立时使用。


就个人而言,我喜欢WaitGroup它,因为它更具可读性和更易于使用。然而,就像通道一样,我不喜欢我们需要传递对 goroutine 的引用,因为这意味着并发逻辑将与您的业务逻辑混合。


所以我想出了这个通用函数来为我解决这个问题:


// Parallelize parallelizes the function calls

func Parallelize(functions ...func()) {

    var waitGroup sync.WaitGroup

    waitGroup.Add(len(functions))


    defer waitGroup.Wait()


    for _, function := range functions {

        go func(copy func()) {

            defer waitGroup.Done()

            copy()

        }(function)

    }

}

下面是一个例子:


func1 := func() {

        for char := 'a'; char < 'a' + 3; char++ {

            fmt.Printf("%c ", char)

        }

}


func2 := func() {

        for number := 1; number < 4; number++ {

            fmt.Printf("%d ", number)

        }

}


Parallelize(func1, func2)  // a 1 b 2 c 3

如果你想使用它,你可以在这里找到它https://github.com/shomali11/util


查看完整回答
反对 回复 2021-11-08
  • 2 回答
  • 0 关注
  • 138 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信