关于并发超时的一点疑问,如何能做到阻塞操作中的超时退出?

panzhongke · 2020-02-23 15:54:24 · 899 次点击

你这个原因应该是:time.sleep会阻塞当前协程,没有cpu时间片来执行,所以你上面那个超时控制,也不好使,个人理解

#3
更多评论
polaris
社区,需要你我一同完善!

使用 context ,https://studygolang.com/articles/13676

话说作为一个程序员,Markdown 都还不会用吗?

#1
package main

import (
    "sync"
    "time"
    "fmt"
    "context"
)

func main() {
    var wg sync.WaitGroup
    start:=time.Now()
    ctx,cancel:=context.WithTimeout(context.Background(),2*time.Second)
    defer cancel()
    wg.Add(1)
    go func(){
        defer wg.Done()
        for{
    select {
    case <-time.After(1 * time.Second):
        fmt.Println("overslept")
        return
    case <-ctx.Done():
        fmt.Println(ctx.Err()) // prints "context deadline exceeded"
        return
    default:
        fmt.Println("dowork")
        time.Sleep(3*time.Second)
        fmt.Println("workdone")
        return
    }
    }
    }()
    time.Sleep(1*time.Second)
    cancel()
    wg.Wait()
fmt.Println(time.Since(start))
fmt.Println("end")
}

运行...

dowork
workdone
3.0001716s
end

成功: 进程退出代码 0.

谢谢@polaris回复,我找了个context代码。测试结果还是没有符合预期。感觉根本原因是select是同步循环。对于阻塞没有办法控制。

#2