3 回答
TA贡献1869条经验 获得超4个赞
默认情况下,goroutine 通信是synchronousand 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
}
}
因为没有接收器,goroutine 挂起并只打印第一个数字。
为了解决这个问题,我们需要定义一个新的 goroutine,它以无限循环的方式从通道中读取数据。
func receive(ch chan int) {
for {
fmt.Println(<- ch)
}
}
然后在main():
func main() {
ch := make(chan int)
go pump(ch)
go receive(ch)
}
Go Playground
TA贡献1860条经验 获得超8个赞
您创建一个无缓冲通道c
与
c := make(chan int)
在无缓冲通道上,操作是对称的,即通道上的每次发送都需要一次接收,每次接收都需要一次发送。您将您的发送i
到频道,goroutine 将其接收到num
. 之后,goroutine 将增量发送num
到通道中,但没有人在那里接收它。
简而言之:声明
c <- num
会阻塞。
您可以使用 1 缓冲通道,这应该可以工作。
您通过等待 10 秒解决了您的代码的另一个问题main
:您不知道 goroutine 何时完成。通常,sync.WaitGroup
在这些情况下使用a 。但是:你的 goroutine 没有完成。chan struct{}
一段时间后在主协程中并select
通过工作协程中的两个通道引入一个是惯用的。
TA贡献1828条经验 获得超13个赞
- 3 回答
- 0 关注
- 158 浏览
添加回答
举报