订阅 MQTT 主题后,防止 go 程序退出 main

更新日期: 2022-07-17 阅读次数: 1885 字数: 271 分类: golang

for 循环会彪 CPU,不好。找了一个 channel 的实现有效解决了这一问题。

实现代码

import (
    "os"
    "os/signal"
    "syscall"
)

func main() {
	channel := make(chan os.Signal, 1)
	signal.Notify(channel, os.Interrupt, syscall.SIGTERM)

	// MQTT 订阅逻辑
	// ...

	<-channel
}

代码分析

channel 的发送和接收数据都是阻塞的。

所以这里可以保证在没有收到消息的时候阻塞住程序的运行,达到防止程序退出的效果。

signal.Notify

但是为何要加上 signal notify?

首先看看 Notify 这个函数的定义:

func Notify(c chan<- os.Signal, sig ...os.Signal)

Notify causes package signal to relay incoming signals to c. If no signals are provided, all incoming signals will be relayed to c. Otherwise, just the provided signals will.

relay 传递,传达信息、新闻的意思。

就是将收到的信号转发给 channel。

如果不加 signal.Notify 会怎样

注释掉 Notify 这行。可以编译成功,但是运行时报错:

> ./hello
hello
fatal error: all goroutines are asleep - deadlock!

goroutine 1 [chan receive]:
main.main()
        /mnt/d/work/test/go_signal/main.go:19 +0x74

处错位置在

<-channel

这行。

参考

  • https://stackoverflow.com/questions/48872360/golang-mqtt-publish-and-subscribe
  • https://pkg.go.dev/os/signal#Notify

关于作者 🌱

我是来自山东烟台的一名开发者,有敢兴趣的话题,或者软件开发需求,欢迎加微信 zhongwei 聊聊, 查看更多联系方式