select + time.After
超时控制
package main
import (
"time"
"fmt"
)
func main() {
ch := make(chan string)
go func() {
time.Sleep(time.Second * 2)
ch <- "result"
}()
select {
case res := <-ch:
fmt.Println(res)
case <-time.After(time.Second * 1):
fmt.Println("timeout")
}
}
使用 channel 来接收 goroutine 返回值
select 语句阻塞等待最先返回数据的 channel,当先接收到 time.After 的通道数据时,select 则会停止阻塞并执行该 case 的代码。此时就实现了对业务代码的超时处理
等待 channel 完成方法
1、select {}
package main
import (
"fmt"
"time"
)
func main() {
go func() {
fmt.Println("start channel: sleep 3s")
time.Sleep(3 * time.Second)
fmt.Println("end channel: sleep 3s")
}()
select {}
}
output
☁ test go run main.go
start channel: sleep 3s
end channel: sleep 3s
fatal error: all goroutines are asleep - deadlock!
goroutine 1 [select (no cases)]:
main.main()
/Users/xiechengqi/test/main.go:16 +0x28
exit status 2
2、sync.WaitGroup
package main
import (
"fmt"
"sync"
"time"
)
func main() {
var wg sync.WaitGroup
wg.Add(1)
go func() {
defer wg.Done()
fmt.Println("start channel: sleep 3s")
time.Sleep(3 * time.Second)
fmt.Println("end channel: sleep 3s")
}()
wg.Wait()
}
output
☁ test go run main.go
start channel: sleep 3s
end channel: sleep 3s
3、chan os.Signal
package main
import (
"fmt"
"os"
"os/signal"
"syscall"
"time"
)
func main() {
go func() {
fmt.Println("start channel: sleep 3s")
time.Sleep(3 * time.Second)
fmt.Println("end channel: sleep 3s")
}()
signalChan := make(chan os.Signal, 1)
signal.Notify(signalChan, syscall.SIGINT, syscall.SIGTERM)
<-signalChan
}
评论区