V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
xmge
V2EX  ›  程序员

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

  •  
  •   xmge · 2020-06-06 15:55:48 +08:00 · 1403 次点击
    这是一个创建于 1631 天前的主题,其中的信息可能已经有所发展或是发生改变。

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

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

    建议看下 context 相关知识
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2718 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 06:51 · PVG 14:51 · LAX 22:51 · JFK 01:51
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.