我试图理解为什么我的代码不起作用,所以我设法在一个更简单的例子中重新创建问题。
我希望这段代码输出字符串“broadcast”“,但它不会输出任何内容。
package main
import (
"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
}
为什么这不起作用?
答案 0 :(得分:7)
您的broadcast
频道无缓冲。这意味着:
handle
频道:主要goroutine阻止直到... select
案例会收到消息...... handler
,将消息发送到broadcast
频道,直到... 就是这样:你的孩子goroutine正在阻止,等待接收消息。同时,您的主要goroutine睡眠,然后到达main
的末尾,退出并终止该程序。
您可以通过多种方式“解决”它:
broadcast
频道缓冲:这样,goroutine会立即发送消息,并在for
循环中返回,然后选择它并按预期打印send
中或通过在循环中调用handler
制作go handler(m)
个(新)goroutine handler
和broadcast
您选择哪一个取决于您尝试解决的确切问题:在这个小例子中,很难找到“最佳”问题。