golang令人困惑的代码RabbitMq永远被阻止!?

yhuiod9q  于 2022-12-28  发布在  Go
关注(0)|答案(1)|浏览(281)

我在使用rabbitMQ时发现了一段有趣的代码

forever := make(chan bool)

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

        }
    }()

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

这是一个代码块,实际上,在正常模式下,这会导致死锁错误,就像enter image description hereenter image description here
但是当我导入rabbitMQ包的时候,这个代码没有引起错误enter image description here为什么会这样?我很困惑。谢谢回答!
期待有人来解释

3xiyfsfu

3xiyfsfu1#

当你使用rabbitmq的时候,变量msgs是一个<-chan amqp.Delivery类型的接收通道--参见文档,即一个接收消息的通道。range循环在每次消息出现时进入goroutine的主体。这是一个很有用的控制序列--阻塞主goroutine,让工作线程等待和处理消息。在这种情况下没有死锁,因为rabbitmq连接将在适当的时候沿着msgs通道发送消息。
在前面的代码中,当你连接到队列并示例化msgs通道时,amqp包会在后台创建另一个goroutine来发送消息到msgs通道。

msgs, err := ch.Consume(
  q.Name, // queue
  "",     // consumer
  true,   // auto-ack
  false,  // exclusive
  false,  // no-local
  false,  // no-wait
  nil,    // args
)

这与前面提到的死锁示例不同,在死锁示例中,没有额外的go例程来将消息发送到forever通道,goroutine进入睡眠状态,不可能被唤醒,这是一个死锁。

相关问题