猿问

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

我试图理解为什么我的代码不起作用,所以我设法在一个更简单的例子中重现了这个问题。


我希望这段代码输出字符串“广播”,但它不输出任何东西。


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

}

为什么这不起作用?


陪伴而非守候
浏览 140回答 1
1回答

红颜莎娜

您的broadcast频道没有缓冲。这意味着:您将消息发送到handle通道:主 goroutine 阻塞,直到...在 goroutine 中,selectcase 得到消息...并调用(在 goroutine 中)handler,它将消息发送到broadcast通道,阻塞直到......就是这样:你的子 goroutine 正在阻塞,等待自己来选择消息。同时,您的主 goroutine 休眠,然后到达末尾main,退出并终止程序。您可以通过多种方式“解决”它:使您的broadcast通道缓冲:这样,goroutine 发送消息,该消息立即成功,并在for循环中返回,选择它并按预期打印使您send的(新)goroutine 在handler中或通过go handler(m)在您的循环中调用让两个不同的 goroutine 监听handler和broadcast你选择哪一个取决于你试图解决的确切问题:在这个小例子中,很难找到一个“最好的”。
随时随地看视频慕课网APP

相关分类

Go
我要回答