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

我有几个 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

}


翻阅古今
浏览 139回答 2
2回答

一只萌萌小番薯

这种实现本身并没有更糟或更好,我已经编写了这种风格的代码,以支持WaitGroup成功使用 a&nbsp;。我也实现了相同的功能,WaitGroup并得到了大致相同的结果。正如评论中提到的,哪个更好是情境化的,并且在许多情况下可能是主观的(区别在于可维护性或可读性而不是性能)。就我个人而言,我真的很喜欢这种风格,因为我要为一个系列中的每个项目分拆一名工人。我已经在干净地关闭时遇到了很多痛苦(在必须以一种或另一种方式提供给工作方法的中止或关闭通道上发出信号)所以我认为将通信循环更进一步是非常方便的并将所有作品包含在一个频道选择中。为了有一个工作中止,你无论如何都必须这样做。

尚方宝剑之说

Channels 和WaitGroups 都可供您酌情使用。对于给定的问题,您的解决方案可以使用渠道WaitGroup或什至两者的组合来解决。据我了解,当您的 goroutine 需要相互通信时,通道更合适(因为它们不是独立的)。WaitGroup通常在您的 goroutine 相互独立时使用。就个人而言,我喜欢WaitGroup它,因为它更具可读性和更易于使用。然而,就像通道一样,我不喜欢我们需要传递对 goroutine 的引用,因为这意味着并发逻辑将与您的业务逻辑混合。所以我想出了这个通用函数来为我解决这个问题:// Parallelize parallelizes the function callsfunc Parallelize(functions ...func()) {&nbsp; &nbsp; var waitGroup sync.WaitGroup&nbsp; &nbsp; waitGroup.Add(len(functions))&nbsp; &nbsp; defer waitGroup.Wait()&nbsp; &nbsp; for _, function := range functions {&nbsp; &nbsp; &nbsp; &nbsp; go func(copy func()) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; defer waitGroup.Done()&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; copy()&nbsp; &nbsp; &nbsp; &nbsp; }(function)&nbsp; &nbsp; }}下面是一个例子:func1 := func() {&nbsp; &nbsp; &nbsp; &nbsp; for char := 'a'; char < 'a' + 3; char++ {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fmt.Printf("%c ", char)&nbsp; &nbsp; &nbsp; &nbsp; }}func2 := func() {&nbsp; &nbsp; &nbsp; &nbsp; for number := 1; number < 4; number++ {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fmt.Printf("%d ", number)&nbsp; &nbsp; &nbsp; &nbsp; }}Parallelize(func1, func2)&nbsp; // a 1 b 2 c 3如果你想使用它,你可以在这里找到它https://github.com/shomali11/util
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go