背景:在嵌入式应用开发中,由于硬件资源受限、外部环境干扰以及软件本身的复杂性,无法绝对保证设备中的某个线程始终稳定运行。即便是最简单的C语言程序,例如仅执行printf
输出"hello world"的功能,也无法确保其能够无限期地持续运行而不发生崩溃。因此,需要引入一个监控线程(或守护线程),专门负责实时监视目标线程的运行状态。一旦检测到目标线程出现异常(如崩溃、卡死等),监控线程应立即采取措施,例如重启目标线程,以恢复系统的正常运行。
为了解决上面的问题,我们衍生出两个模块
守护线程模块:实时监控,需要守护的线程,一经发现线程崩溃,就立刻对其进行重启
开机自启动模块:我们并不期望,设备开机时,每次都要手动开启守护线程模块,而是期望设备一上电,就主动开启这个守护线程
下面代码以监视mosquitto 服务为例
功能: 设备每5秒监视1次 mosquitto 是否在运行,如果没有在运行,则对其重新进行启动
一、守护线程模块
1.创建文件
sudo touch mosquitto_guard.sh
2.修改文件权限
sudo chmod 777 mosquitto_guard.sh
3.打开文件添加代码
vi mosquitto_guard.sh
4.代码
#!/bin/bash
# Mosquitto 服务名称(对于 systemd,通常是 mosquitto)
SERVICE_NAME="mosquitto"
# 检查 Mosquitto 是否正在运行的函数
is_mosquitto_running() {
# 使用 systemctl 检查服务状态
if systemctl is-active --quiet "$SERVICE_NAME"; then
return 0 # 服务正在运行
else
return 1 # 服务未运行
fi
}
# 无限循环,每隔5秒检查一次
while true; do
if ! is_mosquitto_running; then
echo "$(date): Mosquitto 服务未运行,正在尝试重新启动..."
sudo systemctl start "$SERVICE_NAME"
# 检查服务是否成功启动
if is_mosquitto_running; then
echo "$(date): Mosquitto 服务已成功启动。"
else
echo "$(date): 无法启动 Mosquitto 服务,请检查日志以获取更多信息。"
fi
else
echo "$(date): Mosquitto 服务正在运行。"
fi
# 等待5秒
sleep 5
done
5.尝试运行
./mosquitto_guard.sh
二、开机自启动模块
1.创建服务文件
sudo touch my_mosquitto.service
2.修改文件权限
sudo chmod 777 my_mosquitto.service
3.打开文件添加代码
vi my_mosquitto.service
4.代码
[Unit]
Description=My Custom Service
After=network.target # 确保在网络服务启动后启动
[Service]
ExecStart=/usr/local/bin/mosquitto_guard.sh #这里填实际的shell脚本地址
Restart=always # 如果服务崩溃,则自动重启
[Install]
WantedBy=multi-user.target
5.重新加载 systemd 配置
sudo systemctl daemon-reload
6.启用服务(启用服务后,开机会自动启动服务)
sudo systemctl enable my_mosquitto
7.启动服务
sudo systemctl start my_mosquitto