我正在尝试使用工作器goroutines检查直径到一定距离,当我一次做一个瓦片时效果很好,但是当我做一堆时,会出现大幅减速。我认为这是因为即使不再需要它们,许多goroutine仍在运行。我添加了一个故障通道来告诉所有正在运行的goroutine关闭商店,但这样做会导致应用程序挂起。实际上,将任何值传递给频道都会导致应用挂起,即使我没有消费它。
caught := 0
loop:
for angle := float64(0); angle < 360; angle++ {
select {
case <-failChannel:
break loop
default:
log.Print(angle)
}
}
channelOut <- []int{radius, caught}
是使用频道的例程
for {
select {
case circle := <-channelOut:
if circle[1] == 0 {
radiusMap[circle[0]] = 0
if _, radius := testLine(radiusMap); radius <= circle[0] {
failChannel <- 0
}
} else {
radiusMap[circle[0]] = 1
}
default:
}
}
是将int传递给failChannel的循环。我正在做一个int通道,因为我想看看下半径是否失败,如果是这样,就停止。我现在只做任何一个int作为测试。
有没有人知道为什么会挂?它似乎对我没有意义。
答案 0 :(得分:2)
您可以关闭频道以表示完成:
failed := make(chan struct{})
select {
case <-failed:
}
在另一个goroutine中:
close(failed)
会导致failed
案件发生。这适用于在failed
上收听的任意数量的goroutine。但是要小心,只做一次,因为关闭一个已经很近的通道会引起恐慌。你可以使用这种模式:
// A Stopper signals completion over C by closing it when Stop is called
type Stopper struct {
C chan struct{}
once sync.Once
}
// NewStopper creates a new Stopper
func NewStopper() *Stopper {
return &Stopper{
C: make(chan struct{}),
}
}
// Stop closes C. It is safe to call multiple times
func (s *Stopper) Stop() {
s.once.Do(func() {
close(s.C)
})
}