【问题标题】:Defer called in go routine在 goroutine 中调用延迟
【发布时间】:2014-12-18 20:35:41
【问题描述】:

我相信我对正常用例中的 defer 理解得很好。比如这个问题Golang defer behavior中列出的那个。但是,当在不返回的 goroutine 中调用 defer 时,我有点困惑。这是有问题的代码。

func start_consumer() {
    conn, _ := amqp.Dial("amqp://username:password@server.com")
    //defer conn.Close()

    ch, _ := conn.Channel()
    //defer ch.Close()

    q, _ := ch.QueueDeclare(
        "test", // name
        true,   // durable
        false,  // delete when unused
        false,  // exclusive
        false,  // no-wait
        nil,    // arguments
    )

    _ = ch.Qos(
        3,     // prefetch count
        0,     // prefetch size
        false, // global
    )

    forever := make(chan bool)

    go func() {
        for {
            msgs, _ := ch.Consume(
                q.Name, // queue
                "",     // consumer
                false,  // ack
                false,  // exclusive
                false,  // no-local
                false,  // no-wait
                nil,    // args
            )

            for d := range msgs {
                log.Printf("Received a message: %s", d.Body)
                d.Ack(true)
            }

            time.Sleep(1 * time.Second)
        }
    }()

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

这个函数被调用

go start_consumer()

这可能是我对通道如何工作的误解,但我永远不会返回,因为它正在等待传递给它的值。

【问题讨论】:

  • 你到底在问什么?您期望什么行为以及正在发生什么?
  • 很简单,deferred 语句在函数返回时执行。如果函数没有返回,则延迟语句不会执行。

标签: go


【解决方案1】:

上一个问题中引用的 Go 博客的 Defer, Panic, and Recover 帖子很好地解释了 defer 语句的工作原理。

defer 语句将函数调用推送到列表中。保存的调用列表在周围函数返回后执行。 Defer 通常用于简化执行各种清理操作的函数。

在你的情况下,由于 goroutine 没有返回,延迟调用列表将永远不会运行。这使得 defer 语句在这种情况下是不必要的。

【讨论】:

  • 我想知道defer 语句与SIGTERM 信号相关是否有意义?例如:您保持文件打开并接收SIGTERM 信号 - 是否会自动启动defer 函数以正常关闭,或者是否应该手动侦听SIGTERM 信号以调用延迟语句?
  • 并回答我自己的问题:当接收到SIGTERM 或调用os.Exit 时,不会执行任何延迟调用。您必须手动调用已延迟的函数才能执行它们。那么,当你永远不会回来的时候,推迟通话确实是没有意义的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-03-22
  • 1970-01-01
  • 2016-01-28
  • 2012-06-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多