I am very new to go, Can someone help me to reason about this example:
// A concurrent prime sieve
package main
// Send the sequence 2, 3, 4, ... to channel 'ch'.
func Generate(ch chan<- int) {
for i := 2; ; i++ {
ch <- i // Send 'i' to channel 'ch'.
}
}
// Copy the values from channel 'in' to channel 'out',
// removing those divisible by 'prime'.
func Filter(in <-chan int, out chan<- int, prime int) {
for {
i := <-in // Receive value from 'in'.
println("debug", i, prime)
if i%prime != 0 {
out <- i // Send 'i' to 'out'.
}
}
}
// The prime sieve: Daisy-chain Filter processes.
func main() {
ch := make(chan int) // Create a new channel.
go Generate(ch) // Launch Generate goroutine.
for i := 0; i < 10; i++ {
prime := <-ch
print(prime, "
")
ch1 := make(chan int)
go Filter(ch, ch1, prime)
ch = ch1
}
}
There were 2 points I am still very confused, it would be much appreciated if some one can give me some insight about the code.
ch = ch1
it looks elegant, the result is defnitely inaccurate without this line, but I don’t know the details why need to keep updating the input channel with output channel.
I also added some debug information. I am very surprised all non prime number is filtered out very efficiently. i.e 10 (not prime) is just checked once. There was no debug 10 3
after debug 10 2
. I suspect it is if i%prime != 0
do the trick. but how is consistently working with number 9
.
Debug output:
debug 9 2
debug 9 3
debug 10 2
debug 11 2
debug 11 3
This is why it is called a prime sieve. Each channel connects one sieve/Filter to the next one (coarser sieve). That is why you connect input to output sieves:
sieve out multiples of 2 ---> sieve out multiples of 3 ---> sieve out multiples of 5 ---> sieve out ....
You see: What flows out of one sieve goes to the next sieve/Filter.
I do not understand the question. 9 is not devisable by 2 so it passes the 2-Filter. 9 is devisable by 3 so it is stopped by the 3-Filter.
generate
func contains all integer numbers) with a leading number which is the first one (we get it by prime := <-ch
). then it checks if other numbers of the set (numbers sent to channel) is prime from the leadeing number, and put primes to the next set. notice it keeps going in the background (and you will run out of memory space ofc) and proceed to the next level which is using the next number set (or channel) and compare its numbers with leading number and so on. so the first element of every channel is prime (mathematical logic) and other numbers will survive (get to next channel) only if its prime to first element