Go语言两种(超时退出)程序的对比
Go语言实现超时退出有好几种方式,比较常用的有两种:
① 使用定时器 time.After、time.timer 和 select 配合使用
② 使用 Context 包的 context.WithTimeout 方式实现
这两种方式还是有区别的,我比较喜欢使用 context.WithTimeout 的方式、一是比较优雅、二是 context 包是可重入的、比较适合复杂的业务场景
使用定时器 time.After、time.timer 和 select 配合实现超时退出
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| package main
import ( "fmt" "time" )
func main() { done := make(chan bool) timeout := time.Second * 5 go func() { time.Sleep(time.Second * 10) done <- true close(done) }() select { case <-done: fmt.Println("Task finished...") case <-time.After(timeout): fmt.Println("Task timeout...") } }
|
使用 Context 包的 context.WithTimeout 方式实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| package main
import ( "context" "fmt" "time" )
func main() { timeout := time.Second * 5 ctx, cancel := context.WithTimeout(context.Background(), timeout) defer cancel() done := make(chan bool) go func() { time.Sleep(time.Second * 2) done <- true close(done) }() select { case <-done: fmt.Println("Task finished...") case <-ctx.Done(): fmt.Println("Task timeout...") } }
|
总结
1.如果是实现简单的超时程序直接使用 time.After、time.timer 和 select 配合使用就可以、但是实际应用场景大多会是多个协程交互的完成业务,这个
时候使用 time.After 和 select 就比较难以实现复杂的业务场景.
2.Context包是go1.7提供的上下文,原生的并发控制原语;比较适合父协程和子协程和派出孙子协程的并发控制,尤其是超时控制直接就提供了context.WithTimeout 使用起来比较优雅,比较适合复杂的业务场景.