kotlin 流水线素数

kotlin 流水线素数

标签(空格分隔): kotlin


fun numbersFrom(context: CoroutineContext, start: Int) = produce(context) {
    var x = start
    while (true) send(x++) // 从start开始的无限整数流
}
fun filter(context: CoroutineContext, numbers: ReceiveChannel, prime: Int) = produce(context) {
    for (x in numbers) if (x % prime != 0) send(x)
}
fun main(args: Array) = runBlocking {
    var cur = numbersFrom(coroutineContext, 2)
    for (i in 1..10) {
        val prime = cur.receive()
        println(prime)
        cur = filter(coroutineContext, cur, prime)
    }
    coroutineContext.cancelChildren() // 取消所有的子协程,从而让主线程退出
}

粗解:

numbersFrom(2) -> filter(2) -> filter(3) -> filter(5) -> filter(7) ...

filter(3, filter(2, numbers))

https://www.jianshu.com/p/3ffc11978602

http://www.voidcn.com/article/p-cvjkgewg-bxv.html

细解:

首先他的思想就是有一个数据流:
[3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20],他首先用2进行过滤,能被2整除的都去除,
这样就剩下了[3,5,7,9,11,13,15,17,19],然后用3进行过滤【此处遗留3】,
剩下了[5,7,11,13,15,17,19],然后用5进行过滤【此处遗留5】,
剩下了[7,11,13,17,19],此时用7进行过滤【此处遗留7】,
剩下了[11,13,17,19],然后用11进行过滤【此处遗留11】,
剩下了[13,17,19],然后用13进行过滤【此处遗留13】,
剩下了[17,19],然后用17进行过滤【此处遗留17】,
剩下了[19],然后用17进行过滤【此处遗留17
剩下了[]

上面是处理的思想;

**[此处可忽略不看]**具体的操作:首先产生了一个通道数据流numberFrom,发出了数字2,数据流挂起,2被接收,通道数据流numberFrom发出了数字3,又挂起;此时同时打印出了2,然后进入filter(cur,2),在这里面,从cur通道里面取出3,判断之后send(3)挂起,此时numberFrom发出4后挂起,而filter(cur,2)也返回一个通道数据流cur2[针对素数2],然后receive[3],此时cur过滤掉4,打印3,然后filter(cur2,3)开始跑起来,但是目前数据流是空的;
接着看,此时cur通道处理4,直接移除,此时numberFrom发出5后挂起,filter(cur,2)从中取出5,判断send(5)后挂起,[同时numberFrom发出6后挂起,filter(cur,2)直接过滤掉,numberFrom发出7后挂起,filter(cur,2)send(7)后挂起,filter(cur2,3)send(7)后挂起,同时filter(cur3,5)数据流生成,也是空的,此时收到了7,然后send(7)后挂起,又到了一轮的receive],filter(cur2,3)拿到5,send(5)之后挂起,第三轮开启,receive(5)之后打印

上面很乱的,因为把很多同时做的事情不好同时表述:

一次整理:

  • 产生一个通道数据流numberFrom
  • numberFrom发出了数字2,挂起
  • 2被receive,数据流中的2被移除出去 [与此同时,numberFrom发出了数字3]
  • 2被打印
  • 将数据流通道cur=numberFrom 和2传到filter
  • 此时cur中只有3,在filter中经过判断(3%2!=0 ),将3发出去,挂起 //注释1
    • 与此同时,相对于numberFrom数据流来说,3被消耗了移除了,此时发出了数字4,挂起
    • cur2中的3还没有被receive,所以4暂时还在numberFrom数据流管道中
  • 发到哪呢?此时filter返回了一个数据流,也叫cur,[此处是复用,为了区分,我们把它叫做cur2=filter(cur,2)]
  • 第一轮算是结束了,开始第二轮
  • 注释1处,receive了3
    • cur2中从通道中获取到了4,判断被过滤了,挂起
      • numberFrom中的4被消耗了,发出5,挂起
      • cur2中从通道中获取到了5,判断发出5,挂起 //注释2
        • numberFrom中的5被消耗了,发出了数字6
        • 此时cur2还处于挂起状态,所以6暂时还在numberFrom数据流管道中
  • 3被打印
  • 此时将cur2和数字3传到filter中[看注释2,看注释2处,此时cur2中只有数字5,(5%3!=0)]
  • 经过判断,发出了数字5,挂起;同时返回数据流通道cur3=filter(cur2,3)
    • 此时相对于cur2来说,数字5被消耗了,它的挂起结束,他从numberFrom数据通道中获取到了数字6,判断过滤了
    • numberFrom的6被消耗了,发出了数字7,挂起
    • filter(cur,2)中判断(7%2!=0) 发出去了7,挂起 //注释3
    • numberFrom中的7被消耗了,发出了数字8,挂起
  • cur3中进行过滤判断,发出了5,挂起
  • 此时第二轮结束,开始第三轮
  • 5被receive
    • 5被消耗了,看注释3处,通道中发来了7,也是过滤后,7被发出,挂起 //注释4
    • cur2中的7被消耗了,挂起结束,于是接收了numberFrom中的8,被过滤了
    • numberFrom中的8被消耗了,于是发出了9,挂起
    • cur2中接收到了9,不能被2整除,发出去了9,挂起
      • numberFrom中的9被消耗了,发出了10,但是cur2中此时挂起,故暂时还在cur中
    • cur3中收到了9,但是此时cur3刚发出了7,还没有被receive消耗,所以9暂时存在cur2中
  • 5被打印
  • 将cur3和5传参到filter,cur5=filter(cur3,5)
  • 注释4处,此时cur3中只有7,7进行判断过滤,发出了7,挂起
    • 由于cur3中的7被消耗了,他于是接收了9,cur2接收了10,cur中接收了来自numberFrom中的11
      • cur2过滤掉了10,接收了11,cur中接收了来自numberFrom中的12
    • cur3中过滤掉了9
    • cur3中的接收了11,cur2中接收了12,cur中接收了来自numberFrom中的13 //注释5
      • cur2中过滤掉了12,接收了13,cur中接收了来自numberFrom中的14
  • 什么挂起呢?自然是它返回的数据流通道cur5挂起
  • 此时第三轮结束,开始第四轮
  • 7被receive
    • cur5中的7被receive,注释5处,cur5接收了11,cur3接收了13,cur2中接收了14,cur中接收了15
      • cur2过滤掉了14,接收了15,cur中接收了16
  • 7被打印
  • 此时cur7=filter(cur5,7)诞生,它发出了cur5中的11,挂起 //注释6
    • cur5中的11被消耗了,它接收了13,cur3接收了15,cur2接收了16,cur接收了17
      • cur2过滤了16,接收了17,cur接收了18
    • cur3过滤掉了15,接收了17,cur2接收了18,cur接收了19
      • cur2过滤掉了18,接收了19,cur接收了20
  • 此时第四轮结束,开始第五轮
  • 注释6处,11被receive
  • 11被打印
  • cur7中的11被消耗了
  • 依次往前推…

上面的细推如果看懂了,那就基本理解了整个的处理思想和流程,大道化简

cur=numberFrom() -> cur2=filter(context,cur,2) -> cur3=filter(context,cur2,3) -> cur5=filter(context,cur3,5) -> cur7=filter(context,cur5,7)....

//再化简
cur=numberFrom() -> cur2=filter(cur,2) -> cur3=filter(cur2,3) -> cur5=filter(cur3,5) -> cur7=filter(cur5,7)....

//再化简
filter(7,filter(5,filter(3, filter(2, numberFrom))))....

你可能感兴趣的:(kotlin)