英文:
conn.Read goes to infinite loop on closing conn via other go routine
问题
我的代码有点复杂,但简单来说,它有多个Go协程,每个协程都会拨号到不同的TCP服务器,并在可读消息出现在流中时,在一个循环中读取输入。到目前为止还好。现在有另一个Go协程,它管理之前的一组“客户端”,并在用户需要时关闭它们。为此,我将每个“conn”与相应的Go协程客户端关联起来,并关闭它。
我面临的问题是,一旦我调用任何conn对象的close函数,它对应的Read函数就会进入一个无限循环,不断读取空字符串。
我编写了一个简单的代码,类似于我在多个Go协程中处理连接的方式- https://play.golang.org/p/wq7zt9Kqz7
简而言之,我有一个“类”,表示一个远程服务器及其地址、conn和waitgroup。我创建了它的多个实例,并在单独的Go协程中处理它们的输入。然后,在另一个Go协程中,我尝试关闭其中一个实例,但这个read()函数无限循环。
英文:
My code is little complex, but in simple terms it is having multiple go routines, all dial-ing different tcp server and reading the input in a for loop when a readable message is present over the stream. So far so good. Now there is another go routine which manages the previous bunch of 'clients' and closes them when user wants to. For that I have associated each 'conn' with appropriate go routine client and closing that.
The problem what I am facing is as soon as I call the close function of any conn object, its' corresponding Read function goes in an infinite loop reading just the empty strings continuously.
I wrote a simple code which is similar to the way I am handling the connections in multiple go routines- https://play.golang.org/p/wq7zt9Kqz7
TL;DR
In short I have a 'class' which represents one remote server with its address, conn, waitgroup with in it and I am creating its multiple instances and handling for their inputs in separate go routines. And in another go routine I am trying to close one of those instance and this read() goes in a loop indefinitely.
答案1
得分: 1
Read
在关闭的连接上返回一个错误。
应用程序应该在从TCP连接的Read
返回任何错误时退出读取循环。在错误处理中断处理所有这些情况:应用程序在另一个goroutine中关闭连接,对等方关闭连接,网络错误。
在关闭TCP连接的关闭者和该连接上的读取器之间不需要其他同步来协调。
英文:
Read
on a closed connection returns an error.
The application should break out of the read loop on any error returned from Read
on the TCP connection. Break on error handles all of these cases: application closes connection in another goroutine, peer shuts down the connection, network error.
No other synchronization is required to coordinate between a closer of a TCP connection and a reader on that connection.
答案2
得分: 0
我认为你应该使用信号量(通道,在方法内部使用select语句),这样当你调用stop时,它会发送一条消息(布尔值或整数),当方法从该通道接收到消息时,它将关闭连接并停止Go协程。
简单示例:
select {
case <-stopChannel:
// 关闭连接的操作
default:
// 从连接中读取的操作
}
你可以在这里找到更多示例:
Stackoverflow
英文:
I think you should use semaphores(channels,select inside method), so, when you call stop, it will send a message(boolean or int), and when method get message from this channel, it will close connection and stop the go rutine.
Short example
select{
case <- stopChannel:
//Do stuff to close connection
case default:
//Do stuff to read from connection
}
More example you can find there
Stackoverflow
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论