英文:
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包时,这段代码不会引发错误:
为什么会这样?我感到困惑。谢谢回答!期待有人解释一下。
英文:
I found an interesting piece of code when using 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
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 <-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
"", // 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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论