Rhi*_*rva 0 channel go goroutine
下面是一个例子:
func main() {
c := make(chan int)
i := 0
go goroutine(c)
c <- i
time.Sleep(10 * time.Second)
}
func goroutine(c chan int) {
for {
num := <- c
fmt.Println(num)
num++
time.Sleep(1 * time.Second)
c <- num
}
}
Run Code Online (Sandbox Code Playgroud)
我在 goroutine 中尝试做的是从通道接收数字,打印它,递增并在一秒钟后将其发送回通道。在此之后,我想重复这个动作。
但因此,操作只进行一次。
输出:
0
Run Code Online (Sandbox Code Playgroud)
难道我做错了什么?
默认情况下,goroutine 通信是synchronous
and unbuffered
: 发送不会完成,直到有接收者接受该值。必须有一个接收者准备好从通道接收数据,然后发送者可以将它直接交给接收者。
所以通道发送/接收操作阻塞,直到另一端准备好:
1.通道上的发送操作会阻塞,直到接收器可用于同一通道:如果没有接收器的值 on ch
,则不能将其他值放入通道。反之亦然:ch
当通道不为空时,不能发送新值!因此发送操作将等待直到ch
再次可用。
2.通道的接收操作阻塞,直到发送方可用于同一通道:如果通道中没有值,则接收方阻塞。
下面的例子说明了这一点:
package main
import "fmt"
func main() {
ch1 := make(chan int)
go pump(ch1) // pump hangs
fmt.Println(<-ch1) // prints only 0
}
func pump(ch chan int) {
for i:= 0; ; i++ {
ch <- i
}
}
Run Code Online (Sandbox Code Playgroud)
因为没有接收器,goroutine 挂起并只打印第一个数字。
为了解决这个问题,我们需要定义一个新的 goroutine,它以无限循环的方式从通道中读取数据。
func receive(ch chan int) {
for {
fmt.Println(<- ch)
}
}
Run Code Online (Sandbox Code Playgroud)
然后在main()
:
func main() {
ch := make(chan int)
go pump(ch)
go receive(ch)
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
1888 次 |
最近记录: |