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 關注
- 178 瀏覽
添加回答
舉報