【golang开发小技巧】让你再也不用担心常驻协程退出

273 阅读1分钟

golang 是目前为止唯一一个在语言层面支持协程的编程语言。协程又被称为轻量级线程,具有资源占用低,调度速度快、轻量级等特点。也正因为如此,golang开发者可以更加方便的处理并发任务。生产-消费者模式作为一种经典的多线程设计模式,可以说是goper们最熟悉的并发处理模式。

在生产-消费者模式中,通常会通过一个单向channel传递消息,如果消费端因为未知错误导致panic退出,那么生产端将会阻塞,进而影响整个系统的运行。这个时候,如果我们没有正确处理异常或者输出崩溃信息,问题的排查将变得异常困难。

因此,在 golang 中开发生产-消费者模式的多线程任务时,保证消费端常驻协程的正常运行十分重要。在实际开发过程中踩了很多坑之后,我总结了一种基于 recover + 递归的方式,用于保证消费协程永远不会因panic而推出。具体方式如下:

var taskChan = make(chan bool)
func TaskConsumere() {
	go func() {
		defer func() {
			if pErr := recover(); pErr != nil {
				logger.Errorf("TaskConsumere panic:%+v", pErr)
				logger.Errorf("TaskConsumere panic stack :%s", debug.Stack())
				TaskConsumere()
			}
		}()
		for {
			select {
			case <-conf.TaskChan:
				// todo consumer process
			}
		}
	}()
}