软件看门狗的设计与实现

news2024/9/8 23:38:19

在软件开发中,特别是在嵌入式系统、实时系统或任何需要高可靠性和故障恢复能力的领域,看门狗(Watchdog)机制扮演着至关重要的角色。

看门狗通过监控系统的运行状态,并在系统出现故障或停止响应时采取相应措施(如重启系统或触发错误处理机制),来确保系统的稳定性和可靠性。

一 、看门狗的工作原理

看门狗机制通常基于一个定时器,该定时器被设置为在预设的时间间隔内重置(即“喂狗”)。如果系统在该时间间隔内未能重置定时器(即未能“喂狗”),则看门狗将认为系统已经停止响应,并触发一个错误处理函数,该函数可能执行重启系统、记录错误日志或发送警报等操作。

二、设计考虑

在设计软件看门狗时,需要考虑以下几个关键因素:

  1. 超时时间:根据系统的特性和需求,合理设置看门狗的超时时间。超时时间太短可能导致误报,而超时时间太长则可能延迟故障的响应。

  2. 错误处理机制:定义清晰的错误处理流程,包括在系统未响应时应该执行的操作。

  3. 线程安全:由于看门狗可能会被多个线程或组件访问,因此需要确保其对共享资源的访问是线程安全的。

  4. 灵活性:设计应支持多个看门狗实例,以便能够监控系统的不同部分。

三、实践示例

以下是一个在C++中实现的软件看门狗示例,包括看门狗类和看门狗管理类的实现,看门狗基类,该类包含基本的喂狗和超时处理逻辑。看门狗管理类,该类管理多个看门狗实例,并提供添加、删除和更新看门狗的方法。以及如何在主程序中使用它们。

#include <iostream>
#include <vector>
#include <functional>
#include <chrono>
#include <thread>
#include <mutex>
#include <condition_variable>

class WatchdogBase {
protected:
    std::chrono::steady_clock::time_point last_feed_time_;
    std::chrono::seconds timeout_;
    std::function<void()> on_timeout_action_;

    bool is_expired() const {
        return std::chrono::steady_clock::now() - last_feed_time_ > timeout_;
    }

public:
    WatchdogBase(std::chrono::seconds timeout, std::function<void()> on_timeout)
        : timeout_(timeout), last_feed_time_(std::chrono::steady_clock::now()), on_timeout_action_(on_timeout) {}

    virtual void feed() {
        last_feed_time_ = std::chrono::steady_clock::now();
    }

    virtual void check_and_handle_timeout() {
        if (is_expired() && on_timeout_action_) {
            on_timeout_action_();
        }
    }

    virtual ~WatchdogBase() {}
};

class WatchdogManager {
private:
    std::vector<std::unique_ptr<WatchdogBase>> watchdogs_;
    std::mutex mtx_;
    std::condition_variable cv_;
    bool running_ = true;

    void watchdog_thread() {
        while (running_) {
            std::unique_lock<std::mutex> lock(mtx_);
            cv_.wait_for(lock, std::chrono::seconds(1), [this] { return !watchdogs_.empty() || !running_; });

            if (!running_) break;

            for (auto& wd : watchdogs_) {
                wd->check_and_handle_timeout();
            }
        }
    }

public:
    WatchdogManager() {
        std::thread watchdog_thread_([this]() { watchdog_thread(); });
        watchdog_thread_.detach(); // 分离线程
    }

    ~WatchdogManager() {
        {
            std::lock_guard<std::mutex> lock(mtx_);
            running_ = false;
            cv_.notify_one();
        }

        // 等待看门狗线程退出(注意:这里实际上只是发送了停止信号,
        // 并没有等待线程真正结束,因为线程是分离的。如果需要等待,
        // 则需要使用joinable的线程,并在析构时join它。)
    }

    void add_watchdog(std::unique_ptr<WatchdogBase> watchdog) {
        std::lock_guard<std::mutex> lock(mtx_);
        watchdogs_.push_back(std::move(watchdog));
        cv_.notify_one(); // 通知看门狗线程可能有新的看门狗需要检查
    }

    // 其他管理函数,如删除看门狗(注意同步问题)
};

// 示例超时处理函数
void handle_timeout_for_motor() {
    std::cerr << "Motor watchdog timeout! Motor may be stuck." << std::endl;
    // 这里可以添加重启电机、发送警报等逻辑
}

// 示例看门狗实例
class MotorWatchdog : public WatchdogBase {
public:
    MotorWatchdog(std::chrono::seconds timeout, std::function<void()> on_timeout)
        : WatchdogBase(timeout, on_timeout) {}

    // 可以添加特定于电机的喂狗逻辑(如果有的话)
};

int main() {
    WatchdogManager wd_manager;

    // 添加一个电机看门狗实例
    wd_manager.add_watchdog(std::make_unique<MotorWatchdog>(5, handle_timeout_for_motor));

    // 模拟系统工作,定时喂狗
    for (int i = 0; i < 10; ++i) {
        std::cout << "Feeding watchdogs..." << std::endl;

        // 注意:这里我们无法直接访问wd_manager中的看门狗
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1957849.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

顺序表的代码实现

顺序表的代码实现 1.认识什么是顺序表1.1顺序表的优缺点 2.实现顺序表代码准备3.顺序表的代码实现3.1 顺序表结构体的定义3.2 顺序表的初始化3.3 顺序表的销毁3.4 顺序表的输出打印3.5顺序表的扩容3.6 顺序表的头部插入(头插)3.7 顺序表的头部删除(头删)3.8 顺序表的尾部插入(尾…

会话存储、本地存储,路由导航守卫、web会话跟踪、JWT生成token、axios请求拦截、响应拦截

1、会话存储、本地存储 前端浏览器中存储用户信息&#xff0c;会话存储、本地存储、cookie 会话存储&#xff08;sessionStorage&#xff09;&#xff1a;会话期间存储&#xff0c;关闭浏览器后&#xff0c;数据就会销毁 sessionStorage.setItem("account",resp.d…

Unity Apple Vision Pro 开发:如何把 PolySpatial 和 Play To Device 的版本从 1.2.3 升级为 1.3.1

XR 开发社区&#xff1a; SpatialXR社区&#xff1a;完整课程、项目下载、项目孵化宣发、答疑、投融资、专属圈子 &#x1f4d5;教程说明 本教程将介绍如何把 Unity 的 PolySpatial 和 Play To Device 版本从 1.2.3 升级为 1.3.1。 &#x1f4d5;Play To Device 软件升级 ht…

科学设计程序员面试内容,破解“八股文”之弊

“八股文”在实际工作中是助力、阻力还是空谈&#xff1f; 作为现在各类大中小企业面试程序员时的必问内容&#xff0c;“八股文”似乎是很重要的存在。但“八股文”是否能在实际工作中发挥它“敲门砖”应有的作用呢&#xff1f;有IT人士不禁发出疑问&#xff1a;程序员面试考…

数据结构之线性表(顺序表的实现)

目录 一、线性表的原理 二、线性表的实现&#xff08;顺序表&#xff09; 1.定义顺序表 2.初始化顺序表 3.判断顺序表是否为空 4.获取顺序表的长度 5.向顺序表中插入元素 6.删除指定位置的元素 7.遍历顺序表 8.得到指定位置的元素 三、打印测试功能 1.测试 2.结果…

【Ant Design Vue的更新日志】

🌈个人主页: 程序员不想敲代码啊 🏆CSDN优质创作者,CSDN实力新星,CSDN博客专家 👍点赞⭐评论⭐收藏 🤝希望本文对您有所裨益,如有不足之处,欢迎在评论区提出指正,让我们共同学习、交流进步! 以下是Ant Design Vue的更新日志 版本1.7.0(发布日期:2023年4月) …

python之代码简化式(列表、字典生成式,递归函数,迭代器(iter)和生成器(yield)、匿名函数(lambda)的使用)(12)

文章目录 前言1、列表、字典生成式2、递归函数2.1 python中代码的递归深度&#xff08;扩展&#xff09; 3、拓展&#xff1a;迭代器和生成器3.1 迭代器&#xff08;iter&#xff09;3.2 生成器&#xff08;yield&#xff09; 4、匿名函数&#xff08;lambda&#xff09;4.1 ma…

康师傅JAVA核心内容

链接&#xff1a;康师傅JAVA核心内容 (qq.com)

LeetCode刷题笔记第682题:棒球比赛

LeetCode刷题笔记第682题&#xff1a;棒球比赛 题目&#xff1a; 想法&#xff1a; 遍历输入的列表&#xff0c;按照规则将分数和操作依次进行&#xff0c;存储在新建的列表中&#xff0c;最终输出列表中的元素和&#xff0c;代码如下&#xff1a; class Solution:def calPo…

Ubuntu、centos、openEuler安装docker

目录 1.在 Ubuntu 上安装 Docker 1. 1 更新软件包 1. 2 安装必要的依赖 1.3 添加 Docker 的 GPG 密钥 1.4 添加 Docker 仓库 1.5 更新软件包 1.6 安装 Docker 1.7 启动并启用 Docker 服务 1.8 验证安装 1.9 运行测试容器 1.10 非 root 用户运行 Docker 2.在 CentOS…

前端基于 axios 实现批量任务调度管理器 demo

一、背景介绍 这是一个基于 axios 实现的批量任务调度管理器的 demo。它使用了axios、promise 等多种技术和原理来实现批量处理多个异步请求&#xff0c;并确保所有请求都能正确处理并报告其状态。 假设有一个场景&#xff1a;有一个任务列表&#xff0c;有单个任务的处理功能…

OpenGL学习 1

一些唠叨&#xff1a; 很多时候&#xff0c;都被Live2d吸引&#xff0c;去年想给网页加个live2d看板娘&#xff0c;结果看不懂live2d官方给的SDK&#xff0c;放弃了。今天又想弄个live2d桌宠&#xff0c;都已经在网上找到Python 的 Live2D 拓展库了&#xff0c;并提供了用QT实现…

领航者-跟随者编队算法 定义+特性+原理+公式+Python示例代码(带详细注释)

文章目录 引言定义特性基本原理和公式推导基本原理公式推导运动模型领航者的控制跟随者的控制 示例推导 实现步骤和代码实现实现步骤Python代码实现&#xff08;带详细注释&#xff09;代码运行结果代码和图表说明 应用案例优化和挑战优化挑战 结论 引言 在现代科技的发展中&a…

PointCLIP: Point Cloud Understanding by CLIP

Abstract 近年来&#xff0c;基于对比视觉语言预训练(CLIP)的零镜头和少镜头学习在二维视觉识别中表现出了令人鼓舞的效果&#xff0c;该方法在开放词汇设置下学习图像与相应文本的匹配。然而&#xff0c;通过大规模二维图像-文本对预训练的CLIP是否可以推广到三维识别&#x…

【状语从句】

框架 概念&#xff0c;特点主将从现连接词时间条件地点结果方式让步原因目的比较省略倒装 解读 1【概念&#xff0c;特点】 一个完整的句子&#xff0c;去修饰另一个完整句子中的动词&#xff0c;称为状语从句&#xff1b;特点&#xff1a;从句完整&#xff0c;只用考虑连接词是…

扩展------正向代理和反向代理怎么理解?

今天看博客园&#xff0c;突然看到正向代理和反向代理&#xff0c;发现自己还不会就稍微研究了一下。 正向代理----(看做是服务员) 当我们进饭店吃饭&#xff0c;我们不可能会直接去后厨叫厨师给我们做菜&#xff0c;而是通过服务员去通知&#xff0c;这个就叫做正向代理。 再…

keras在GPU环境下配置,conda虚拟环境并安装TensorFlow,cudatoolkit,cudann和jupyter等

前言&#xff1a;要有版本意识 在我个人的多次配置环境过程中&#xff0c;很多时候失败或者后序出现问题&#xff0c;往往都是版本不匹配的问题。所以在本次安装中&#xff0c;提前重点了解了下版本匹配情况。各位千万不要跳过这部分&#xff0c;因为这不仅是基础知识了解的过…

君子学习,是为了修养自己

98天 保护自己最好的方式&#xff1a; 恢复良知的明和诚&#xff0c;就能照见万物&#xff0c;能常觉、常照&#xff0c;任何东西都无所遁形。&#xff08;相信直觉&#xff09; 君子学习&#xff0c;是为了修养自己。 从不担忧别人会欺骗自己&#xff0c;只是永远不欺骗自己的…