Go 我应该使用同步通道还是阻塞通道?
我有几个go例程,我使用无缓冲通道作为同步机制 我想知道这是否有什么错误(例如,与WaitGroup实现相比)。我知道的一个已知的“缺点”是,两个go例程可能会一直被阻塞,直到第三个(最后一个)例程完成,因为通道没有缓冲,但我不知道内部/这到底意味着什么Go 我应该使用同步通道还是阻塞通道?,go,Go,我有几个go例程,我使用无缓冲通道作为同步机制 我想知道这是否有什么错误(例如,与WaitGroup实现相比)。我知道的一个已知的“缺点”是,两个go例程可能会一直被阻塞,直到第三个(最后一个)例程完成,因为通道没有缓冲,但我不知道内部/这到底意味着什么 func main() { chan1, chan2, chan3 := make(chan bool), make(chan bool), make(chan bool) go fn(chan1) go fn(chan
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
}
func main(){
chan1,chan2,chan3:=make(chan bool),make(chan bool),make(chan bool)
go fn(通道1)
go fn(通道2)
go fn(chan3)
res1、res2、res3:=这个实现本身并不差或更好,我编写了这种风格的代码,支持成功地使用WaitGroup
。我还使用WaitGroup
实现了相同的功能,并得到了大致相同的结果。如评论中所述,更好的是情景性的,可能是在许多情况下是主观的(区别在于可维护性或可读性,而不是性能)
就个人而言,我真的很喜欢这种风格,因为我在一个集合中每个项目都有一个worker。我已经在干净地关闭时遇到了很多麻烦(在abort或close通道上发出信号,该通道必须以某种方式提供给worker方法)因此,我认为将通信循环向前推进一步并将所有工作包含在通道选择中是非常方便的。为了使工作中止,您无论如何都必须这样做。通道和WaitGroup
s都可供您酌情使用。对于给定的问题,您的解决方案可以使用channe解决ls或WaitGroup
或两者的组合
据我所知,当您的goroutines需要相互通信时(如它们不是独立的),通道更合适。WaitGroup
通常在您的goroutines相互独立时使用
就个人而言,我喜欢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
func1:=func(){
对于char:='a';char<'a'+3;char++{
fmt.Printf(“%c”,字符)
}
}
func2:=func(){
对于数字:=1;数字<4;数字++{
fmt.Printf(“%d”,编号)
}
}
并行化(func1,func2)//a1b2c3
如果你想使用它,你可以在这里找到它这个问题的答案取决于你的实际问题和你的实际约束。我只是想知道是否会有拥塞/竞争问题。例如,程序由于某些原因而卡住/死锁。