开心一刻
物质的背后是“事”,把事做到极致,物质自来丰盈;
事的背后是“人”,把人做好,事自然成功;
人的背后是“命”,把命的维度修好,自然生运;
运的背后是“道”,有一颗助人、爱人的善心,就是人間正道;
正道存,天地助之。事成!人成!命成!运成!!
题目介绍
使用golang的并发特性实现的素数筛。
package main
import "fmt"
func generateNatural() chan int {
ch := make(chan int)
go func() {
for i := 2; ; i++ {
ch <- i
}
}()
return ch
}
func primeFilter(in <-chan int, prime int) chan int {
out := make(chan int)
go func() {
for {
if i := <- in; i % prime != 0 {
out <- i
}
}
}()
return out
}
func main() {
ch := generateNatural()
for i := 0; i< 100; i++ {
prime := <- ch
fmt.Printf("%v: %v\n", i + 1, prime)
ch = primeFilter(ch, prime)
}
}
并发版本的素数筛是一个经典的并发案例,通过它可以更深刻地理解Go语言并发特性。
在上面实现素数筛地代码中,generateNatural()函数是用来生成自然数序列goroutine,因为要一直生产自然数,所以使用死循环。
PrimeFilter()函数是内部启动地Goroutine生成序列,返回过滤后序列对应地通道,每次调用PrimeFilter()都会创建一个新通道,通道中保存地就是新出现的素数。
最终的情况我觉得就像是下面的图片,只有出现新素数的时候PrimeFilter()才会返回,并将这个新素数读出来,不是素数的数据会在中途过滤掉。例如自然数4,它会先从第一个通过经过,但是由于不满足"i % prime != 0"的条件,所以被过滤掉了,然后自然数5是一个新素数,自然就能够被返回。
但是我看了书上也说,素数筛虽然展示了一种优雅的并发编程结构,但是因为每个并发体处理的任务粒度太细微,程序整体的性能并不理想。对于细粒度的并发程序,CSP模型中固有的消息传递的代价太高了。我写的代码中还只是打印前100个素数,如果要打印上千万个素数,那么这个素数筛子就会有千万个之多。
文中都是我个人的理解,如有错误的地方欢迎下方评论告诉我,我及时更正,大家共同进步