登录
首页 >  Golang >  Go问答

怎样让这段 golang for-select 代码生效?

来源:stackoverflow

时间:2024-03-10 10:09:25 257浏览 收藏

一分耕耘,一分收获!既然都打开这篇《怎样让这段 golang for-select 代码生效?》,就坚持看下去,学下去吧!本文主要会给大家讲到等等知识点,如果大家对本文有好的建议或者看到有不足之处,非常欢迎大家积极提出!在后续文章我会继续更新Golang相关的内容,希望对大家都有所帮助!

问题内容

问题

如何让下面的代码在3秒后打印“quit”?

代码

package main

import (
    "fmt"
    "time"
)

func main() {
    quit := make(chan struct{})
    tasks := make(chan struct{})

    go func(){
      time.Sleep(1 * time.Second)
      tasks <- struct{}{}
    }()

    go func(){
      time.Sleep(3 * time.Second)
      quit <- struct{}{}
    }()

    for {
        select {
        case <-quit:
            fmt.Println("QUIT")
            return
        case <-tasks:
            fmt.Println("Doing")
            // do some long time jobs more than 10 seconds
            time.Sleep(10 * time.Second)
        }
    }
}

观察结果

上面的代码打印“doing”。并睡眠 10 秒,然后打印“quit”。 如何中断这个睡眠,让它在3秒后接收quit通道并打印“quit”?

看来selectcasetasks阻止,并且3秒后不会从quit通道接收消息。


正确答案


为了发出异步任务结束的信号,最佳实践是关闭通道,这对于防止导致各种死锁的误用非常重要。 在您的原始代码中,我会编写 close(quite) 而不是 quit <- struct{}{} 请记住,在关闭时读取不会阻塞并且始终返回零值,这就是技巧。

无论如何,除此之外,解决问题的一种优雅方法是结合使用 context.contexttime.after

time.after 将帮助您阻止可选择的任务集。

context.context 更适合处理此类信号。

https://play.golang.org/p/ZVsZw3P-YHd

package main

import (
    "context"
    "log"
    "time"
)

func main() {
    log.Println("start")
    defer log.Println("end")
    ctx, cancel := context.WithCancel(context.Background())
    tasks := make(chan struct{})

    go func() {
        time.Sleep(1 * time.Second) // a job
        tasks <- struct{}{}
    }()

    go func() {
        time.Sleep(3 * time.Second) // a job
        cancel()
    }()

    for {
        select {
        case <-ctx.Done():
            log.Println("QUIT")
            return
        case <-tasks:
            log.Println("Doing")
            // do some long time jobs more than 10 seconds
            select {
            case <-ctx.Done():
                return
            case <-time.After(time.Second * 10):
            }
        }
    }
}

好了,本文到此结束,带大家了解了《怎样让这段 golang for-select 代码生效?》,希望本文对你有所帮助!关注golang学习网公众号,给大家分享更多Golang知识!

声明:本文转载于:stackoverflow 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>