【发布时间】:2020-10-03 05:25:18
【问题描述】:
我正在用 Go 编写程序,同时也是使用 Go 通道的 RMQ 消费者,并遇到了这些场景。
“go forever channel”阻塞主线程,直到它从其他 go 例程获得停止信号。
但下面的程序1告诉死锁错误,程序2工作正常,没有死锁错误, 为什么会这样?
程序 1:Go 例程打印元素循环和死锁错误
package main
import "fmt"
func main() {
stopProgram := make(chan bool)
go func() {
for i := 0; i < 5; i++ {
fmt.Println("hello ",i)
}
// Send signal through stopProgram to stop loop
//stopProgram <- true
}()
// your problem will wait here until it get stop signal through channel
<-stopProgram
fmt.Println("after forever channel")
}
输出
hello 0
hello 1
hello 2
hello 3
hello 4
fatal error: all goroutines are asleep - deadlock!
goroutine 1 [chan receive]:
main.main()
/home/main.go:26 +0x73
方案 2:去路由循环接收 RMQ 交付并且没有死锁
package main
import (
"fmt"
)
func main() {
// assuming some code of registring exchange and queues with rabbitmq
msgs, err := ch.Consume(
q.Name, // queue
"", // consumer
true, // auto-ack
false, // exclusive
false, // no-local
false, // no-wait
nil, // args
)
stopProgram := make(chan bool)
go func() {
for d := range msgs {
fmt.Println("reveived message ",d.Body)
}
}()
// your problem will wait here until it get stop signal through channel
<-stopProgram
fmt.Println("after forever channel")
}
任何人都可以在这里清除永久频道在这里如何工作的事情(我是 GO 新手)吗?
我的假设 - 在程序 1 中,go 路由在打印 hello 5 次后结束,并且当前例程/任何其他例程中没有无限执行或停止信号以永远进入通道。
如果我们想永远使用 go 通道(或阻塞主要的 Go 例程以留在特定的 go 例程中),我们必须确保这些事情
无论是 go 例程都确保无限执行或
Go 例程将停止信号发送到永久通道。
【问题讨论】:
标签: go rabbitmq deadlock channel producer-consumer