【问题标题】:conn.Read goes to infinite loop on closing conn via other go routineconn.Read 在通过其他 go 例程关闭 conn 时进入无限循环
【发布时间】:2017-06-29 13:02:38
【问题描述】:

我的代码有点复杂,但简单来说,它有多个 go 例程,所有调用不同的 tcp 服务器并在流中存在可读消息时在 for 循环中读取输入。到目前为止,一切都很好。现在有另一个 go 例程,它管理前面的一堆“客户端”并在用户想要时关闭它们。为此,我已将每个“conn”与适当的 goroutine 客户端相关联并关闭它。

我面临的问题是,只要我调用任何 conn 对象的 close 函数,其对应的 Read 函数就会进入无限循环,不断读取空字符串。

我编写了一个简单的代码,类似于我在多个 go 例程中处理连接的方式-https://play.golang.org/p/wq7zt9Kqz7

TL;DR

简而言之,我有一个“类”,它代表一个远程服务器,其中包含它的地址、conn、waitgroup,我正在创建它的多个实例并在单独的 go 例程中处理它们的输入。在另一个 go 例程中,我试图关闭其中一个实例,并且这个 read() 无限期地循环。

【问题讨论】:

  • 您是否正确关闭了等待组(我之所以问,是因为示例代码没有说明任何内容)此外,如果您正确关闭子例程,示例代码也没有记录。

标签: go tcp goroutine


【解决方案1】:

Read 在关闭的连接上返回错误。

应用程序应在 TCP 连接上从Read 返回的任何错误中跳出读取循环。 Break on error 处理所有这些情况:应用程序在另一个 goroutine 中关闭连接,对等方关闭连接,网络错误。

不需要其他同步来协调 TCP 连接的较近者和该连接上的读取器。

【讨论】:

    【解决方案2】:

    我认为你应该使用信号量(channels,select inside method),所以当你调用stop时,它会发送一个消息(boolean or int),当方法从这个channel获取消息时,它会关闭连接并停止去套路。

    简短的例子

    select{
    case <- stopChannel:
    //Do stuff to close connection
    case default:
    //Do stuff to read from connection
     }
    

    您可以在此处找到更多示例 Stackoverflow

    【讨论】:

    • 频道是我的第一选择,但问题是我希望我动态创建“远程服务器”的实例,但我不知道如何处理频道。在等待组的情况下,每次收到新服务器的请求时,我都很容易在循环中使用 wg.Add(1)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多