golang 的超时处理之不返回怎么办?

2020-06-06 15:55:48 +08:00
 xmge

在使用 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")
	}
}
1400 次点击
所在节点    程序员
3 条回复
reus
2020-06-06 16:08:11 +08:00
ctx 就是给你传到业务流程里的,一直阻塞那就是程序有问题,要修改程序,而不是在外面擦屁股
newtype0092
2020-06-07 11:16:14 +08:00
你这种超时控制就是允许异常超时的啊,按 LS 的话说就是该擦的屁股擦了你还嫌废纸。
如果大并发不想阻塞就异步处理呗。
useben
2020-06-07 11:45:34 +08:00
ctx, _ := context.WithTimeout(context.TODO(), time.Second*3)

你外部都忽略了返回的 cancel, 外部都没有 cancel(), 控制毛线

建议看下 context 相关知识

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/679194

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX