为了账号安全,请及时绑定邮箱和手机立即绑定

无法让并发按我的预期工作

无法让并发按我的预期工作

Go
陪伴而非守候 2022-01-10 14:51:21
我试图理解为什么我的代码不起作用,所以我设法在一个更简单的例子中重现了这个问题。我希望这段代码输出字符串“广播”,但它不输出任何东西。package mainimport (    "fmt"    "time")type hub struct {    handle    chan []byte    broadcast chan []byte}func (h *hub) init() {    for {        select {        case m := <-h.handle:            handler(m)        case _ = <-h.broadcast:            fmt.Println("broadcasted")        }    }}var socketHub = hub{    handle:    make(chan []byte),    broadcast: make(chan []byte),}func main() {    go socketHub.init()    m := []byte("this is the message")    socketHub.handle <- m    time.Sleep(time.Second * 2)}func handler(m []byte) {    // Do some stuff.    socketHub.broadcast <- m}为什么这不起作用?
查看完整描述

1 回答

?
红颜莎娜

TA贡献1842条经验 获得超13个赞

您的broadcast频道没有缓冲。这意味着:

  1. 您将消息发送到handle通道:主 goroutine 阻塞,直到...

  2. 在 goroutine 中,selectcase 得到消息...

  3. 并调用(在 goroutine 中)handler,它将消息发送到broadcast通道,阻塞直到......

就是这样:你的子 goroutine 正在阻塞,等待自己来选择消息。同时,您的主 goroutine 休眠,然后到达末尾main,退出并终止程序。

您可以通过多种方式“解决”它:

  • 使您的broadcast通道缓冲:这样,goroutine 发送消息,该消息立即成功,并在for循环中返回,选择它并按预期打印

  • 使您send的(新)goroutine 在handler中或通过go handler(m)在您的循环中调用

  • 让两个不同的 goroutine 监听handlerbroadcast

你选择哪一个取决于你试图解决的确切问题:在这个小例子中,很难找到一个“最好的”。


查看完整回答
反对 回复 2022-01-10
  • 1 回答
  • 0 关注
  • 139 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号