golang如何终止一个有阻塞io读操作的goroutine?
本文介绍了golang如何终止一个有阻塞io读操作的goroutine?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
问 题
比如开启一个goroutine阻塞读取UDP
read, _, err := socket.ReadFromUDP(data)
如果系统的signal没有注册的情况下,默认信号会终止这个阻塞调用,进而终止goroutine。问题来了,程序为了stop gracefully,捕获了一些信号(SIGTERM
等),如何让上面的goroutine终止呢?
我目前的办法是,读取调用设置一个deadline
,外部通过chan让这个goroutine结束。但问题是,这样做,总有一个延迟,最坏的情况是deadline
设置的最大延迟:
for {
select {
//外部通过close(done)通知退出
case <- done:
logp.Info("trap listen stop")
return
default:
//设置一个timeout,2s,那么最坏的情况下,可能要等2s,这个goroutine才会退出
if err = socket.SetReadDeadline( time.Now().Add( time.Duration(time.Second * 2) ) ); err != nil {
logp.Err("fail to set read dead line, %v", err)
break
}
read, _, err := socket.ReadFromUDP(data)
if nerr, ok := err.(net.Error); ok && nerr.Timeout() {
continue
}
if err != nil {
logp.Err("fail to read UDP message, %v", err)
break
}
...
}
}
有没有更好的办法解决这个问题呢?
解决方案
想要结束stocket.ReadFromUDP内部的循环监听 我想到的就两种方式,第一关闭UDP链接,第二设置deadline。
这篇关于golang如何终止一个有阻塞io读操作的goroutine?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文