在使用 select{}
进行超时控制的方案中,如果做任务的协程迟迟不能返回(接近阻塞),怎么处理?
在大并发的场景下,就会创建的大量的阻塞的协程。
package main
import (
"context"
"fmt"
"time"
)
func main() {
ctx, _ := context.WithTimeout(context.TODO(), time.Second*3)
go CallWithTimeOut(ctx)
time.Sleep(time.Second * 2)
}
func CallWithTimeOut(ctx context.Context) {
c := make(chan bool)
go func() {
// 真正的业务流程,比如进行 http 请求,syscall 等
//模拟延迟 2s 。
// 问题: 如果这个协程一直阻塞怎么办?
time.Sleep(time.Second * 2)
c <- true
}()
select {
case <- ctx.Done():
fmt.Println("timeout")
case <- c:
fmt.Println("job finished")
}
}
1
reus 2020-06-06 16:08:11 +08:00
ctx 就是给你传到业务流程里的,一直阻塞那就是程序有问题,要修改程序,而不是在外面擦屁股
|
2
newtype0092 2020-06-07 11:16:14 +08:00
你这种超时控制就是允许异常超时的啊,按 LS 的话说就是该擦的屁股擦了你还嫌废纸。
如果大并发不想阻塞就异步处理呗。 |
3
useben 2020-06-07 11:45:34 +08:00
ctx, _ := context.WithTimeout(context.TODO(), time.Second*3)
你外部都忽略了返回的 cancel, 外部都没有 cancel(), 控制毛线 建议看下 context 相关知识 |