麻烦帮我理一下这个书中的示例,go 的协程,实在是理不顺了,万分感谢。

代码如下,问题:main()中for循环在不断启用新的协程,ch = ch1,这一句,它是不需要等待的吧,直接从 ch1 := make(chan int) 得到空的信道吗?

如果能讲解一下执行顺序,感激不尽,这段代码输出的是 2 3 5 7 11 13 17 19 …,能否帮我讲解下 11 是怎么得到的就行,我不清楚这中间协程和ch=ch1哪个在前在后执行的。

package main

import "fmt"

// 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'.
    }
}

func filter(in, out chan int, prime int) {
    for {
        i := <-in // Receive value of new variable 'i' from 'in'.
        if i%prime != 0 {
            out <- i // Send 'i' to channel 'out'.
        }
    }
}

// The prime sieve: Daisy-chain filter processes together.
func main() {
    ch := make(chan int) // Create a new channel.
    go generate(ch)      // Start generate() as a goroutine.
    for {
        prime := <-ch
        fmt.Print(prime, " ")
        ch1 := make(chan int)
        go filter(ch, ch1, prime)
        ch = ch1
    }
}
go
最佳答案

这个首先要理解质数产生的机理。代码的走势就是有很多个filter()协程,而且这个协程出来的第一个元素就是质数。这些filter()协程是有顺序的,像一个链式一样的关系,前一个协程写入的数据,后一个协程拿出来。prime就是前一个协程的写入的第一个元素。这是前三个协程,可以参考一下

func filter1(in, out chan int, prime int) {
    for {
        i := <-in //这个通道是generate的通道
        if i%prime != 0 {  //prime=2,
            out <- i //所有不能被2整除的数写入通道,ch2 {3,5,7,9,11,13,15,17,19,21...}
        }
    }
}
func filter2(in, out chan int, prime int) {
    for {
        i := <-in //这个通道是ch2
        if i%prime != 0 {  //ch2的第一个元素3,prime=3,
            out <- i //所有不能被3整除的数写入通道,ch3 {5,7,11,13,17,19,....}
        }
    }
}
func filter3(in, out chan int, prime int) {
    for {
        i := <-in //这个通道是ch3
        if i%prime != 0 {  //ch3的第一个元素5,所以prime=5,
            out <- i //所有不能被3整除的数写入通道,ch3 {7,11,13,17,....}
        }
    }
}

3年前 评论
讨论数量: 4
taadis

乍一看好像你不对, 再一看好像我不对, 楞一看好像题不对.

3年前 评论

@taadis 我在 filter() 里打印了,发现一点规律,但是 main() 里加了一些print打印的状态值又不能反应协程的真实顺序,还是有点乱。

3年前 评论
pardon110

去掉该段代码,一个goroutine边生成数据,主goroutine边消费数据。

        ch1 := make(chan int)
        go filter(ch, ch1, prime)
        ch = ch1

上述代码不仅在不停的生成新的过滤goroutine,同时也在不停生成新的ch1通道
把ch1赋值给ch,是为了下一步循环做铺垫,所谓的赋值,即是把下一轮的数据流ch指定为本轮的输出流ch1:本轮输出流流向下轮输入流,如此往复…,在每一轮循环中都会产生唯一的一个素数,这个素数用来筛选出上一轮流过来的数据流并流向下一轮,每一轮数据流中最小的那个就是素数

// 第一轮  筛出2
3 5 7 9 11 13...
// 第二轮  筛出3
5 7 11 13...
//第三轮 筛出5
7 11 13 17 19...
3年前 评论

这个首先要理解质数产生的机理。代码的走势就是有很多个filter()协程,而且这个协程出来的第一个元素就是质数。这些filter()协程是有顺序的,像一个链式一样的关系,前一个协程写入的数据,后一个协程拿出来。prime就是前一个协程的写入的第一个元素。这是前三个协程,可以参考一下

func filter1(in, out chan int, prime int) {
    for {
        i := <-in //这个通道是generate的通道
        if i%prime != 0 {  //prime=2,
            out <- i //所有不能被2整除的数写入通道,ch2 {3,5,7,9,11,13,15,17,19,21...}
        }
    }
}
func filter2(in, out chan int, prime int) {
    for {
        i := <-in //这个通道是ch2
        if i%prime != 0 {  //ch2的第一个元素3,prime=3,
            out <- i //所有不能被3整除的数写入通道,ch3 {5,7,11,13,17,19,....}
        }
    }
}
func filter3(in, out chan int, prime int) {
    for {
        i := <-in //这个通道是ch3
        if i%prime != 0 {  //ch3的第一个元素5,所以prime=5,
            out <- i //所有不能被3整除的数写入通道,ch3 {7,11,13,17,....}
        }
    }
}

3年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!