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

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

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

Go
守着星空守着你 2021-09-10 15:27:33
所以我正在使用 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 一样工作,通道接受的默认值将被发送
查看完整描述

1 回答

?
翻翻过去那场雪

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

您通常可以使用共享的退出频道来执行此操作,并进行一些计数。


func (p *Player) writeToSocket(quit <-chan struct{})

    defer func() {

        p.closeEventChan <- true

    }()

    for {

        select {

        case <-quit:

            return

        case m := <-p.writeChan:

            // Do stuff

        // Case where writeChan is closed, but quit isn't

        default:

            return

        }

    }

}



func (p *Player) readFromSocket(quit <-chan struct{})

    defer func() {

        p.closeEventChan <- true

    }()

    for {

        select {

        case <-quit:

            return

        default:

            // Do stuff

        }

    }

}


func (p *Player) EventLoop() {

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

    quit := make(chan struct{})

    go p.readFromSocket(quit)

    go p.writeToSocket(quit)


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

    <-p.closeEventChan

    close(quit)

    // This is superfluous here, but in a different case

    // you loop over the remaining number of workers using a NumWorkers variable

    for i := 0; i < 1; i++ {

        <-p.closeEventChan

    }

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

}

这里的想法是:


所有工人在关闭时通过通道通知中央程序,然后返回。

所有工作人员在广播退出消息时返回(通过关闭)。

中央循环在第一个工人退出后关闭退出通道,然后等待其余的退出。


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

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信