您好,匿名用户

golang如何终止一个有阻塞io读操作的goroutine?

0 投票

比如开启一个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
            }
            ...
        }
}

有没有更好的办法解决这个问题呢?

用户头像 提问 2017年 5月10日 @ Lux 中士 (1,092 威望)
分享到:

1个回答

0 投票

Go 1.7中可以使用 context canel

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

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

用户头像 回复 2017年 5月10日 @ Anivia 下士 (961 威望)
提一个问题:

相关问题

0 投票
1 回复 127 阅读
用户头像 提问 2017年 5月16日 @ Singed 下士 (970 威望)
0 投票
1 回复 60 阅读
0 投票
1 回复 90 阅读
0 投票
1 回复 74 阅读
用户头像 提问 2017年 6月6日 @ Ezreal 中士 (1,081 威望)
0 投票
1 回复 173 阅读
用户头像 提问 2017年 4月1日 @ Heimerdinger 中士 (1,031 威望)

欢迎来到随意问技术百科, 这是一个面向专业开发者的IT问答网站,提供途径助开发者查找IT技术方案,解决程序bug和网站运维难题等。
温馨提示:本网站禁止用户发布与IT技术无关的、粗浅的、毫无意义的或者违法国家法规的等不合理内容,谢谢支持。

欢迎访问随意问技术百科,为了给您提供更好的服务,请及时反馈您的意见。
...