【go】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。

Go 1.7中可以使用 context canel

func (d *Dialer) DialContext(ctx context.Context, network, address string) (Conn, error)

参考:https://golang.org/pkg/net/#D...

回答

以上是 【go】golang如何终止一个有阻塞io读操作的goroutine? 的全部内容, 来源链接: www.h5w3.com/115101.html

回到顶部