Я учащийся. Чтобы лучше понять заботу и питание каналов и гортанов, я пытаюсь построить сито Эратосфена как набор гортинов, соединенных в трубопровод по каналам.Что такое элегантный способ закрыть цепочку каналов, связанных каналами?
Вот что я до сих пор:
// esieve implements a Sieve of Eratosthenes
// as a series of channels connected together
// by goroutines
package main
import "fmt"
func sieve(mine int, inch chan int) {
start := true // First-number switch
ouch := make(chan int) // Output channel for this instance
fmt.Printf("%v\n", mine) // Print this instance's prime
for next := <-inch; next > 0; next = <-inch { // Read input channel
fmt.Printf("%v <- %v\n",mine,next) // (Trace)
if (next % mine) > 0 { // Divisible by my prime?
if start { // No; is it the first number through?
go sieve(next, ouch) // First number - create instance for it
start = false // First time done
} else { // Not first time
ouch <- next // Pass it to the next instance
}
}
}
}
func main() {
lim := 30 // Let's do up to 30
fmt.Printf("%v\n", 2) // Treat 2 as a special case
ouch := make(chan int) // Create the first segment of the pipe
go sieve(3, ouch) // Create the instance for '3'
for prime := 3; prime < lim; prime += 2 { // Generate 3, 5, ...
fmt.Printf("Send %v\n", prime) // Trace
ouch <- prime // Send it down the pipe
}
}
И насколько она идет, она прекрасно работает.
Однако, когда я заканчиваю основной цикл, main
выходит до того, как все номера, все еще находящиеся в конвейере sieve
экземпляров, распространяются до конца.
Что является самым простым, самым элегантным или общепринятым способом сделать основную процедуру ожидания завершения набора goroutines (о котором он только «знает» первого)?
Простым и рекомендуемым решением является использование другого канала, который 'main' будет блокировать и получать результат операции. – creker
Возможный дубликат работы [Shutdown «рабочий» после процедуры, когда буфер пуст] (http://stackoverflow.com/questions/32383063/shutdown-worker-go-routine-after-buffer-is-empty) – icza
@icza: I частично соглашаться; этот вопрос включает более простую (сортирующую) топологию. В моем случае только последний goroutine в трубе должен сигнализировать об отключении, * как только он знает, что он последний *. Я думаю, что я близок к окончательному ответу, который я в конечном итоге разместил здесь. BTW восхитительные конструкции для использования! –