正在使用net.Conn.Read()
,发现这货除了net.close()
,似乎没有其他办法把read()
函数给主动返回。
这样也太扯淡了吧,至少提供个select readset
或者epoll readset
,这样类似的操作吧。
1
sujin190 2020-11-20 15:32:29 +08:00
为啥要取消?是你理解有问题吧,除非连接关闭,否则确实无需返回啊,如果你有其他事情要干,那么再开个携程就是了啊,如果需要读超时啥的,这个超时本来就需要新开协程来干的啊
|
2
lwch 2020-11-20 15:33:13 +08:00
可以设 timeout
|
3
nuk 2020-11-20 15:33:40 +08:00
不是有 setdeadline 啥的么。。
|
5
lwch 2020-11-20 15:38:09 +08:00
io.Read 的阻塞操作本来就是为了让出时间片给别的协程做调度用的,所以 go 里面不存在 noblock 的 io 操作
|
6
howellz OP @sujin190 取消是一个太常见的场景了,最极端的就我想中止这个携程,但是我现在不能关闭这个 conn 。当然您也许会继续质疑我为什么要关闭这个携程。。。
|
8
mepwang 2020-11-20 15:53:54 +08:00 via iPhone
给它的 socket 发点东西😅
|
9
icexin 2020-11-20 15:55:00 +08:00
在另外一个地方调用 conn. SetReadDeadline,参数设置一个距离很短的 deadline 就可以立马让 Read 返回错误。
比如 conn.SetReadDeadline(time.Now()) |
11
jokefun 2020-11-20 15:59:12 +08:00
读了一半 cancel 了之后这个 net.Conn 怎么办呢?没读完的 bytes 下次接着读吗?
|
12
lxz6597863 2020-11-20 16:50:35 +08:00
把 chan 和 net.Conn 封装个 Reader
|
13
sujin190 2020-11-20 17:42:43 +08:00
@howellz #6 这个场景确实有,但是不是这么用的,按你这么说其实就是数据处理逻辑和读写逻辑被分离了,按 go 的设计和习惯用法,那么应该是 read 连接这个协程只负责处理读,读处理的数据通过 channl 传给另外逻辑处理协程来完成,那么这个协程才应该依据是否超时等其他情况觉得是否取消处理,读写本来就应该和连接绑定,而数据逻辑处理才应该考虑中途退出,这才是符合 go 的习惯处理方式
|
14
wellsc 2020-11-20 17:49:55 +08:00
gmp 这玩意儿就是把协程 schedulder 封装进了一个框架里面,给协程封装框架的语言除了 golang 还有 erlang 系,反正框架有框架的好处,也有框架的坏处,坏处就是自己调度起来有点麻烦吧
|
15
reus 2020-11-20 18:45:00 +08:00
conn.SetReadDeadline(time.Now().Add(-time.Hour))
|
16
howellz OP @sujin190 您设计的场景不是没有考虑过.但这种异步传递消息的方式,需要多次分配`buf []byte`。如果是同步处理,在`read`后处理完了,`buf`可以让下一次`read`重用。在负荷非常大的场景,尽量少拷贝、少分配、少传递是我需要考虑的一个重要问题。
|
17
lesismal 2021-02-24 15:30:52 +08:00
|