Golang 令人困惑的代码 RabbitMq 永久阻塞了!?

huangapple go评论158阅读模式
英文:

golang Confusing code RabbitMq forever blocked !?

问题

我在使用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 here
enter image description here

但是当我导入rabbitMQ包时,这段代码不会引发错误:

enter image description here

为什么会这样?我感到困惑。谢谢回答!期待有人解释一下。

英文:

I found an interesting piece of code when using rabbitMQ

forever := make(chan bool)

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

		}
	}()

	log.Printf(&quot; [*] Waiting for messages. To exit press CTRL+C&quot;)
	&lt;-forever

This is a block of code ,
In fact, in normal mode,
this would cause a deadlock error,
Like this
enter image description here
enter image description here

But when I import rabbitMQ package , this code does not cause an error
enter image description here
Why is that? I'm confused.
Thanks for answer!

Expect someone to explain

答案1

得分: 0

当你使用rabbitmq时,msgs变量是一个接收类型为<-chan amqp.Delivery的通道,即一个接收消息的通道。range循环每次出现一条消息时都会进入循环体。这是一个有用的控制序列,它会阻塞主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
)

这与提供的死锁示例不同,在那些示例中,没有其他goroutine来通过forever通道发送消息。goroutine进入睡眠状态,没有机会被唤醒。这是一个死锁。

英文:

When you are using rabbitmq, the msgs variable is a receiving channel of type &lt;-chan amqp.Delivery - see docs i.e a channel receive messages. The range loop is enters the body each time a message appears. This is a useful control sequence - block the main goroutine whilst the worker awaits and processes messages. There is no deadlock in this case as rabbitmq connection will send messages down the msgs chan when appropriate.

In earlier code, when you connect to the queue and instantiate the msgs channel, the amqp package çreates another goroutine in the background to send messages down the msgs channel.

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

This is unlike the deadlock examples provided, where there is no additional go-routines to send messages down the forever channel. The goroutine goes to sleep and there is no chance of it being awakened. It is a deadlock.

huangapple
  • 本文由 发表于 2022年12月27日 04:21:39
  • 转载请务必保留本文链接:https://go.coder-hub.com/74923733.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定