package main
import"fmt"funcmain(){
ch :=g()for i :=1; i <=100; i++{
pp :=<-ch
fmt.Printf("%v:%v\n", i, pp)
ch =p(i, ch, pp)}}funcg()chanint{
ch :=make(chanint)gofunc(){// 本协程只会一致往cnt=1那个接收协程里面写入for i :=2;; i++{
ch <- i
}}()return ch
}funcp(cnt int, in <-chanint, p int)chanint{
out :=make(chanint)gofunc(cnt int){// cnt表示哪个go func运行for{// p 和 cnt有对应关系,详细可以看打印结果if i :=<-in; i%p !=0{
fmt.Printf("cnt:%d,out<-%d,%d %% %d != 0\n", cnt, i, i, p)
out <- i // 写入out会作为下一个协程的in}}}(cnt)return out
}
没写过这么666的代码。但我的映像中,切片、map、interfere{}、chan等都是默认为地址,你看chan是需要make出来的,所以可以从这方面研究吧。
一直很困惑
ch = PrimeFilter(ch, prime)
这段代码是怎么运行的虽然看起来很奇怪,但真的能跑起来,如果直接写
PrimeFilter(ch, prime)
输出的结果是不对的你把ch看成一个对象变量就行了,这段代码就是为每找到一个素数,就为从自然数读取中的过滤器上加一道,所以找到的素数越多,那么Chan的连路也会越多,对应启动的go协程也会越多 但是比一般的查找逻辑优化了CPU,使用更多的内存。
(ps:你不发文本,我懒得敲函数名了,嘿嘿。)仔细研究了一下你这个程序,确实666。因为发送协程一直在g里面写入,接收有很多个协程,每个协程接收的数据是上一个接收协程判断成功后发送的数据,因此那个过滤的func确实能达到过滤的效果。就像一堆小球滚下楼梯,每个楼梯都要判断哪些小球能滚到下个楼梯,一些不满足条件的会在中途某些接收协程里面踢出掉,这些踢出的是不会传到下个接收协程。这种程序一般用于学习吧,理解起来是有点绕。
多说一句,这些中途的chan貌似没办法close掉,而协程一直存在,不会被GC掉,该程序如果不退出那这些chan就要算内存泄漏了。
感谢