子goroutine出现all goroutines are asleep - deadlock!问题

来源:3-6 RabbitMQ工作模式---Simple模式(下)

Rayer

2020-06-20

代码1:

	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

代码2:

func main() {
	forever := make(chan bool)
	xx := make(chan bool)
	msgs := (<-chan bool)(xx)

	go func() {
		log.Println("aaa")
		for d := range msgs {
			log.Println("Received a message:", d)
		}
	}()
	log.Print("bbb")
	<-forever
}

老师,这代码1是项目中的消费端代码,其中中的msgs其实是一个用于接收的单向通道,这里forever也是一个通道,但这里却不会出现fatal error: all goroutines are asleep - deadlock!

而代码2是我用一个单向通道去模拟msgs的,这却会报以上错误,为啥啊?

写回答

2回答

不吃洋葱的小胡子大叔

2023-01-07

因为xx是channel, 需要一头写入另一头才能读取. 所以xx需要另开一个goroutine有写入才行.  否则msgs是从xx里读的, 没有写入就死锁了.

func main() {
    forever := make(chan bool)
    xx := make(chan bool, 10000)
    msgs := (<-chan bool)(xx)

    go func() {
        log.Println("aaa")
        for d := range msgs {
            log.Println("Received a message:", d)
            time.Sleep(time.Second)
        }
    }()
    go func() {
        for {
            xx <- true
            time.Sleep(time.Second)
        }
    }()
    log.Print("bbb")
    <-forever
}


0
0

Cap

2020-06-22

这里牵涉到死锁的概念,如果是同学这样写的话 当程序执行到 range msgs 的时候会阻塞等等写入,这时候两个goroutines(main,go func)都在等带信息的写入。导致了死锁。

同学可以在 import 里面 加 _ "github.com/streadway/amqp"  试下



0
2
Cap
是在你写的test代码上加,如果要用,正常导入就可以了。
2020-06-22
共2条回复

全流程开发 GO实战电商网站高并发秒杀系统

运用架构设计与系统化思维,从容应对不同流量等级的“秒杀”场景

1462 学习 · 443 问题

查看课程