1 回答

TA贡献1860条经验 获得超9个赞
行为无法预测。有时您的程序会工作,有时则不会。我已经解释了问题发生的代码(带有注释)。
package main
import (
"fmt"
"time"
)
func main() {
c := make(chan int)
fmt.Println("initialized channel")
// This is a receiver receiving from c (spawned goroutine)
go receiver(c)
// This is a sender (spawned goroutine)
go helper(c)
// This is again a receiver receiving from c
// NOTE: As reciever and helper are spawned in
// separate goroutine, control eventually reaches
// here.
// Behaviour is unpredictable as sometimes the data
// sent to the channel might be recieved here and
// sometimes it might be recieved by the receiver function.
for x := range c {
fmt.Println(x)
}
}
func helper(c chan int) {
time.Sleep(time.Second * 3)
c <- 5
time.Sleep(time.Second * 3)
c <- 4
// When this close is triggered, the receiver in main
// could get exited as the signal to stop ranging is sent
// using signal. Right after that the main function ends
// such that data recieved by the receiver couldn't get
// printed (sometimes it would work as well) i.e., main
// exited right before fmt.Println(x) in receiver function.
close(c)
}
func receiver(c chan int) {
for x := range c {
fmt.Println(x)
}
}
要修复它,你可以试试这个。还有更多可能的解决方案,但这已经足够了。我已经删除了time.Sleep电话,因为它们与我们无关并且为简洁起见。
package main
import (
"fmt"
)
func main() {
// Initialize the channel
c := make(chan int)
// Spawn a goroutine that sends data to the
// channel. Also, it is expected from the sender
// only to close the channel as it only knows
// when then send stops. Send to a closed
// channel would panic.
go send(c)
// As send is running asynchronously, control
// reaches here i.e., the receiver. It ranges until
// c is closed and is guaranteed to receive every
// date sent to channel c and then exit.
for x := range c {
fmt.Println(x)
}
}
// send data to c
func send(c chan int) {
c <- 5
c <- 4
close(c)
}
- 1 回答
- 0 关注
- 82 浏览
添加回答
举报