【问题标题】:Golang: forever channelGolang:永远的频道
【发布时间】:2018-04-26 00:04:17
【问题描述】:

只是有一个问题,这里发生了什么?

forever := make(chan bool)

log.Printf(" [*] Waiting for messages. To exit press CTRL+C")
<-forever

【问题讨论】:

  • 打开一个 delve 会话并反汇编,或者只是 [s,d]trace 进程。您会看到 icza 在他的回答中所说的正是正在发生的事情:&lt;-forever 是一个阻塞操作。同样forever&lt;-true 也会阻塞(因为没有例程从通道读取)
  • 优秀的Go tour中全面覆盖了频道。

标签: go channel


【解决方案1】:

该代码创建一个无缓冲通道,并尝试从中接收。

而且由于没有人在其上发送任何内容,因此它本质上是一个永久阻塞操作。

目的是为了防止 goroutine 结束/返回,很可能是因为有其他 goroutine 同时做一些工作,或者它们等待某些事件或传入消息(比如你的日志消息说)。

需要的是,如果没有这个,应用程序可能会在不等待其他 goroutines 的情况下退出。也就是说,如果main goroutine 结束,程序也结束。引用自Spec: Program execution:

程序执行从初始化主包开始,然后调用函数 main。当该函数调用返回时,程序退出。它不会等待其他(非main)goroutine 完成。

查看此答案以了解类似和更多技术:Go project's main goroutine sleep forever?

频道介绍见What are channels used for?

【讨论】:

    【解决方案2】:

    问题中的代码可能来自RabbitMQ golang教程here

    这里有一个更扩展的部分,还有我自己的一些赞扬:

        ...
        // create an unbuffered channel for bool types.
        // Type is not important but we have to give one anyway.
        forever := make(chan bool) 
    
        // fire up a goroutine that hooks onto msgs channel and reads
        // anything that pops into it. This essentially is a thread of
        // execution within the main thread. msgs is a channel constructed by
        // previous code.
        go func() {
            for d := range msgs {
                log.Printf("Received a message: %s", d.Body)
            }
        }()
    
        log.Printf(" [*] Waiting for messages. To exit press CTRL+C")
        // We need to block the main thread so that the above thread stays
        // on reading from msgs channel. To do that just try to read in from
        // the forever channel. As long as no one writes to it we will wait here.
        // Since we are the only ones that know of it it is guaranteed that
        // nothing gets written in it. We could also do a busy wait here but
        // that would waste CPU cycles for no good reason.
        <-forever
    

    【讨论】:

      猜你喜欢
      • 2016-09-23
      • 1970-01-01
      • 2019-02-02
      • 1970-01-01
      • 1970-01-01
      • 2018-10-12
      • 2018-02-02
      • 1970-01-01
      • 2017-06-11
      相关资源
      最近更新 更多