golang 2 go 例程,如果一个终止终止另一个

所以我正在使用 gorillas websocket 库,当我收到一个连接时,我正在构建一个 websocket 服务器 我创建了 2 个 go 例程,一个用于读取来自客户端的传入消息,另一个用于侦听发送到通道的传入消息,然后发送它们给客户。


func (p *Player) EventLoop() {

    l4g.Info("Starting player %s event loop", p)

    go p.readFromSocket()

    go p.writeToSocket()


    //blocks until we receive an interrupt from the read channel

    <-p.closeEventChan

    p.cleanup() //nothing else to do so lets cleanup

}


func (p *Player) writeToSocket() {

    for m := range p.writeChan {

        if p.conn == nil {

            break

        }


        if reflect.DeepEqual(network.Packet{}, m) == true {

            break

        }


        if err := p.conn.WriteJSON(m); err != nil {

            break

        }

    }

    p.closeEventChan <- true

}


func (p *Player) readFromSocket() {

    for {

        if p.conn == nil {

            break

        }


        m := network.Packet{}


        if err := p.conn.ReadJSON(m); err != nil {

            break

        }

    }

    p.closeEventChan <- true

}


func (p *Player) Cleanup() {


    //make sure the channels get a close message which will break us out of the go routines

    close(p.writeChan)

    close(p.closeEventChan)


    //only close the connection if we have a connection

    if p.conn != nil {

        p.conn.Close()

        p.conn = nil

    }

}

我的问题是如果我们离开readFromSocket()循环Cleanup()被调用但是我们永远不会离开writeToSocket()循环!这个问题可以在这个 go playground https://play.golang.org/p/49bh7bbbG- 中更简单地演示


我们如何解决这个问题,所以如果我们离开writeToSocket()循环,我们也会离开readFromSocket()循环,反之亦然?


我的印象是,这就像您在通道 ( close(p.writeChan))上调用 close 一样工作,通道接受的默认值将被发送


守着星空守着你
浏览 184回答 1
1回答

翻翻过去那场雪

您通常可以使用共享的退出频道来执行此操作,并进行一些计数。func (p *Player) writeToSocket(quit <-chan struct{})&nbsp; &nbsp; defer func() {&nbsp; &nbsp; &nbsp; &nbsp; p.closeEventChan <- true&nbsp; &nbsp; }()&nbsp; &nbsp; for {&nbsp; &nbsp; &nbsp; &nbsp; select {&nbsp; &nbsp; &nbsp; &nbsp; case <-quit:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return&nbsp; &nbsp; &nbsp; &nbsp; case m := <-p.writeChan:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // Do stuff&nbsp; &nbsp; &nbsp; &nbsp; // Case where writeChan is closed, but quit isn't&nbsp; &nbsp; &nbsp; &nbsp; default:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }}func (p *Player) readFromSocket(quit <-chan struct{})&nbsp; &nbsp; defer func() {&nbsp; &nbsp; &nbsp; &nbsp; p.closeEventChan <- true&nbsp; &nbsp; }()&nbsp; &nbsp; for {&nbsp; &nbsp; &nbsp; &nbsp; select {&nbsp; &nbsp; &nbsp; &nbsp; case <-quit:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return&nbsp; &nbsp; &nbsp; &nbsp; default:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // Do stuff&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }}func (p *Player) EventLoop() {&nbsp; &nbsp; l4g.Info("Starting player %s event loop", p)&nbsp; &nbsp; quit := make(chan struct{})&nbsp; &nbsp; go p.readFromSocket(quit)&nbsp; &nbsp; go p.writeToSocket(quit)&nbsp; &nbsp; //blocks until we receive an interrupt from the read channel&nbsp; &nbsp; <-p.closeEventChan&nbsp; &nbsp; close(quit)&nbsp; &nbsp; // This is superfluous here, but in a different case&nbsp; &nbsp; // you loop over the remaining number of workers using a NumWorkers variable&nbsp; &nbsp; for i := 0; i < 1; i++ {&nbsp; &nbsp; &nbsp; &nbsp; <-p.closeEventChan&nbsp; &nbsp; }&nbsp; &nbsp; p.cleanup() //nothing else to do so lets cleanup}这里的想法是:所有工人在关闭时通过通道通知中央程序,然后返回。所有工作人员在广播退出消息时返回(通过关闭)。中央循环在第一个工人退出后关闭退出通道,然后等待其余的退出。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go