2 回答
TA贡献1811条经验 获得超4个赞
并且在一切都完成后出现了一些涉及死锁的错误启动之后,这是我的解决方案正常工作:
// esieve implements a Sieve of Eratosthenes
// as a series of channels connected together
// by goroutines
package main
import "fmt"
func sieve(mine int, // This instance's own prime
inch chan int, // Input channel from lower primes
done chan int, // Channel for signalling shutdown
count int) { // Number of primes - counter
start := true // First-number switch
ouch := make(chan int) // Output channel, this instance
fmt.Printf("%v ", mine) // Print this instance's prime
for next := <-inch; next > 0; next = <-inch { // Read input channel
if (next % mine) > 0 { // Divisible by my prime?
if start { // No; first time through?
go sieve(next, ouch, done, count+1) // First number,
// create instance for it
start = false // First time done
} else { // Not first time
ouch <- next // Pass to next instance
}
}
}
if start { // Just starting?
close(done) // Yes - we're last in pipe - signal done
print("\n",count," primes\n") // Number of primes/goroutines
} else {
close(ouch) // No - send the signal down the pipe
}
}
func main() {
lim := 100 // Let's do up to 100
done := make(chan int) // Create the done return channel
ouch := make(chan int) // Create the first segment of the pipe
go sieve(2, ouch, done, 1) // Create the first instance for '2'
for prime := 3; prime < lim; prime += 1 { // Generate odd numbers
ouch <- prime // Send numbers down the pipe
}
close(ouch) // Send the done signal down the pipe
<- done // and wait for it to come back
}
与许多其他语言相比,Go 对于这种编程的优雅和简单给我留下了深刻的印象。当然,疣是我自己要求的。
如果在这里合适,我欢迎批评性评论。
TA贡献1804条经验 获得超3个赞
至于您的标题问题,当您不再需要它们时杀死工作程序 goroutine: 您可以使用 Done 成语。从封闭通道读取产生零值。
创建一个新频道done。当从这个通道读取成功时,goroutines 知道他们应该退出。当您拥有所需的所有值时,关闭主通道。
检查您是否可以从 channel 读取done,并通过返回退出,或者在可用时从 next 读取。这部分替换了nextfor 循环中的赋值:
select {
case <-done:
return
case next = <- inch:
}
在通道上测距也有效,因为关闭该通道退出循环。
至于反过来,你的身体问题,等待一组goroutines完成:
使用sync.WaitGroup.
var wg sync.WaitGroup
wg.Add(goroutineCount)
当每个 goroutine 完成时:
wg.Done()
或者使用延迟:
defer wg.Done()
等待所有这些都报告为完成:
wg.Wait()
在您的示例中,只需wg.Add(1)在启动新 goroutine 时调用,然后再调用wg.Done()和返回即可。只要您只达到零一次,就会wg.Wait()按预期工作,所以wg.Add(1)在wg.Done.
- 2 回答
- 0 关注
- 138 浏览
添加回答
举报