time.After通过返回定时通道实现超时控制,结合select可避免Goroutine阻塞,在超时后触发分支;若提前完成需用time.NewTimer并调用Stop防止资源泄露,而context则适用于更复杂的超时场景。

time.After
<-chan Time
select
解决方案
time.After
select
time.After
package main
import (
    "fmt"
    "time"
)
func main() {
    ch := make(chan string)
    go func() {
        // 模拟一个耗时操作
        time.Sleep(2 * time.Second)
        ch <- "数据来了!"
    }()
    select {
    case data := <-ch:
        fmt.Println("接收到数据:", data)
    case <-time.After(1 * time.Second):
        fmt.Println("超时了!")
    }
    fmt.Println("程序结束")
}在这个例子中,我们创建了一个 Goroutine,它会在 2 秒后向
ch
main
select
ch
time.After(1 * time.Second)
ch
time.After
case <-time.After(1 * time.Second)
立即学习“go语言免费学习笔记(深入)”;
这种方式避免了主程序无限期地等待,提高了程序的健壮性。
在使用
time.After
select
time.After
time.After
一种常见的解决方案是使用
time.NewTimer
timer.Stop()
time.NewTimer
Timer
package main
import (
    "fmt"
    "time"
)
func main() {
    ch := make(chan string)
    timer := time.NewTimer(1 * time.Second) // 创建一个 Timer
    go func() {
        time.Sleep(2 * time.Second)
        ch <- "数据来了!"
    }()
    select {
    case data := <-ch:
        fmt.Println("接收到数据:", data)
        if !timer.Stop() { // 尝试停止 Timer
            <-timer.C // 如果 Timer 已经触发,则从 channel 读取数据,防止阻塞
        }
    case <-timer.C:
        fmt.Println("超时了!")
    }
    fmt.Println("程序结束")
}在这个改进后的例子中,如果从
ch
Timer
timer.Stop()
Timer
timer.C
timer.Stop()
false
timer.C
context
context.WithTimeout
context.WithDeadline
context.Done()
虽然
context
time.After
time.After
package main
import (
    "context"
    "fmt"
    "time"
)
func main() {
    ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second)
    defer cancel() // 确保 cancel 函数被调用
    ch := make(chan string)
    go func(ctx context.Context) {
        time.Sleep(2 * time.Second)
        select {
        case ch <- "数据来了!":
        case <-ctx.Done():
            fmt.Println("Goroutine 超时退出")
            return
        }
    }(ctx)
    select {
    case data := <-ch:
        fmt.Println("接收到数据:", data)
    case <-ctx.Done():
        fmt.Println("主程序超时!")
        fmt.Println(ctx.Err()) // 打印超时错误
    }
    fmt.Println("程序结束")
}在这个例子中,我们创建了一个带有 1 秒超时的 context。Goroutine 监听
ctx.Done()
ctx.Done()
time.After
time.Sleep
time.Sleep
time.After
time.Sleep
time.After
select
选择使用哪个函数取决于具体的应用场景。如果只需要简单地暂停一段时间,
time.Sleep
time.After
以上就是Golang的time.After函数在处理并发超时时的巧妙用法的详细内容,更多请关注php中文网其它相关文章!
 
                        
                        每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
 
                 
                                
                                 收藏
收藏
                                                                             
                                
                                 收藏
收藏
                                                                             
                                
                                 收藏
收藏
                                                                            Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号