这个例子中的通道是如何工作的?

huangapple go评论72阅读模式
英文:

How the channels work in this example?

问题

这是一个质数筛选的示例代码。

package main

func Generate(ch chan<- int) {
  for i := 2; ; i++ {
    ch <- i
  }
}

func Filter(in <-chan int, out chan<- int, prime int) {
  for {
    i := <-in
    if i%prime != 0 {
      out <- i
    }
  }
}

func main() {
  ch := make(chan int)
  go Generate(ch)
  for i := 0; i < 10; i++ {
    prime := <-ch
    print(prime, "\n")
    ch1 := make(chan int)
    go Filter(ch, ch1, prime)
    ch = ch1
  }
}

我理解的是这行代码:

prime := <-ch

这个通道正在等待输入,并将其赋值给 prime。那么为什么在调用下一条语句

print(prime, "\n")

时并没有打印出所有的数字呢?

如果我删除最后三行代码:

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

那么从2到11的所有数字都会被打印出来。那么这行代码 ch = ch1 是做什么用的呢?

谢谢。

英文:

This is is an example of prime number sieve

package main

func Generate(ch chan&lt;- int) {
  for i := 2; ; i++ {
    ch &lt;- i
  }
}

func Filter(in &lt;-chan int, out chan&lt;- int, prime int) {
  for {
    i := &lt;-in
    if i%prime != 0 {
      out &lt;- i
    }
  }
}

func main() {
  ch := make(chan int)
  go Generate(ch)
  for i := 0; i &lt; 10; i++ {
    prime := &lt;-ch
    print(prime, &quot;\n&quot;)
    ch1 := make(chan int)
    go Filter(ch, ch1, prime)
    ch = ch1
  }
}

What I understand is this line of code

prime := &lt;-ch

the channel is waiting for an input and assigns to prime. So, why all the numbers are not printed when the next statement is called

print(prime, &quot;\n&quot;)

If I remove these last 3 lines

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

then all numbers are printed from 2 to 11. What does this line do ch = ch1?

Thanks

答案1

得分: 3

你的代码的输出是:

2
3
5
7
11
13
17
19
23
29

所以过程如下:

i=0,

prime := <-ch 之后,prime=2,ch={3};

go Filter(ch, ch1, prime) 之后,标记为 Filter0,在函数 Filter0 中,通道 in 将是 3,4,5,6 ...,而通道 out 将是 3,5,7 ...;

ch = ch1 之后,ch={3},它将是 3,5,7。

i=1,

prime := <-ch 之后,prime=3,ch={5},为什么 ch 中有 5?因为现在的 ch 是上一次循环中的 ch1

go Filter(ch, ch1, prime) 之后,标记为 Filter1,在函数 Filter1 中,通道 in 将是 5,7,9,11 ...,而通道 out 将是 5,7,11 ...;

ch = ch1 之后,ch={3},它将是 5,7,11。

i=2,同理。

这就是输出的过程。

英文:

Your code's output is :

2
3
5
7
11
13
17
19
23
29

So the procedure is like this :

i=0,

after prime := &lt;-ch , prime=2, ch = {3};

after go Filter(ch, ch1, prime) , mark as Filter0,in function Filter0 channel in will be 3,4,5,6 ... and channel out will be 3,5,7 ...;

After ch = ch1, So ch = {3}, which will be 3,5,7.

i=1,

after prime := &lt;-ch ,prime= 3, ch ={5},why is there 5 in ch?'Cause now ch is the ch1 in last loop ;

after go Filter(ch, ch1, prime) , mark as Filter1,in function Filter1 channel in will be 5,7,9,11 ... and channel out will be 5,7,11 ...;

After ch = ch1, So ch = {3}, which will be 5,7,11.

i=2, the same .

That how it output.

答案2

得分: 1

不打印所有数字的原因是因为在循环的每次迭代中,通道不是相同的。它创建了一个新的通道ch1,并将ch中的值过滤到ch1中,然后将ch赋值给ch1,以便下一次迭代中的ch是上一次迭代的新通道(即ch1),并且那里的值已经被Filter goroutine过滤。

以下是另一种可能更容易理解的写法:

for i := 0; i < 10; i++ {
    prime := <-ch
    print(prime, "\n")
    oldch := ch          // 这里oldch引用了旧的通道
    ch = make(chan int)  // 这里用新的通道替换了ch
    go Filter(oldch, ch, prime) // 这里将oldch中的值通过过滤器应用到ch中
}
英文:

The reason not all numbers are printed is because it's not the same channel in each iteration of the loop. It creates a new channel ch1 and filters values from ch into ch1 and then it assigns ch to ch1 so that the next iteration ch is the new channel from the previous iteration (there known as ch1) and the values there have been filtered by the Filter goroutine.

Here is another way to write it that may make more sense to you:

for i := 0; i &lt; 10; i++ {
    prime := &lt;-ch
    print(prime, &quot;\n&quot;)
    oldch := ch          //here oldch references the old channel
    ch = make(chan int)  //and here ch is replaced with a new channel
    go Filter(oldch, ch, prime) //and here a filter is applied to values from oldch to ch
}

huangapple
  • 本文由 发表于 2014年8月28日 20:42:25
  • 转载请务必保留本文链接:https://go.coder-hub.com/25549135.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定