news 2026/7/14 2:54:57

小项目实验:Qt/C++共享内存进程监控系统

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
小项目实验:Qt/C++共享内存进程监控系统

需求:

写一个程序a和一个监控程序b,a定周期写一个数据c,并且每次递增,数据是uchar 类型就可以,达到最大值后从0重新开始。 程序b通过共享内存定周期读取a写的c的值,写数据的周期是一秒,读数据的周期是5秒,b如果一个周期内发现数据没有变化,证明a出问题了,就重启a

我将为您设计基于Qt/C++的共享内存通信与进程监控系统。以下是分步骤的解决方案:

解决方案架构

  1. 共享内存设计:使用Qt的QSharedMemory实现跨进程数据交换
  2. 进程管理:通过QProcess启动/监控/重启子进程
  3. 定时机制:使用QTimer实现精确的周期控制
  4. 错误检测:通过数据变化检测实现故障判断

程序A实现(数据写入端)

cpp

// a.cpp #include <QCoreApplication> #include <QSharedMemory> #include <QTimer> class DataWriter { public: DataWriter(const QString &sharedKey) : m_sharedKey(sharedKey), m_shm(sharedKey) { // 初始化共享内存 if (!m_shm.create(1)) { if (m_shm.error() == QSharedMemory::AlreadyExists) { m_shm.attach(); } } // 设置定时器 QTimer *timer = new QTimer(this); connect(timer, &QTimer::timeout, this, &DataWriter::updateData); timer->start(1000); // 1秒周期 } private: void updateData() { m_shm.lock(); uchar *data = static_cast<uchar*>(m_shm.data()); *data = (*data + 1) % 256; // 递增并处理溢出 m_shm.unlock(); } private: QString m_sharedKey; QSharedMemory m_shm; }; int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); DataWriter writer("Global\\MySharedMem"); return a.exec(); }

程序B实现(监控端)

cpp

// b.cpp #include <QCoreApplication> #include <QSharedMemory> #include <QTimer> #include <QProcess> class ProcessMonitor { public: ProcessMonitor(const QString &sharedKey, const QString &programPath) : m_sharedKey(sharedKey), m_programPath(programPath), m_shm(sharedKey), m_process(nullptr) { // 启动被监控程序 restartProcess(); // 设置监控定时器 QTimer *monitorTimer = new QTimer(this); connect(monitorTimer, &QTimer::timeout, this, &ProcessMonitor::checkStatus); monitorTimer->start(5000); // 5秒周期 } private: void restartProcess() { if (m_process) { m_process->terminate(); m_process->waitForFinished(3000); delete m_process; } m_process = new QProcess(this); connect(m_process, &QProcess::errorOccurred, [this](QProcess::ProcessError) { qDebug() << "Process error:" << m_process->errorString(); }); m_process->start(m_programPath); } void checkStatus() { static uchar lastValue = 0; static int staleCount = 0; m_shm.lock(); uchar *data = static_cast<uchar*>(m_shm.constData()); uchar currentValue = data ? *data : 0; m_shm.unlock(); // 检测数据是否变化 if (currentValue == lastValue) { staleCount++; if (staleCount >= 1) { // 单次检测到未变化即重启 qDebug() << "Process stalled! Restarting..."; restartProcess(); staleCount = 0; } } else { lastValue = currentValue; staleCount = 0; } } private: QString m_sharedKey; QString m_programPath; QSharedMemory m_shm; QProcess *m_process; }; int main(int argc, char *argv[]) { QCoreApplication b(argc, argv); ProcessMonitor monitor("Global\\MySharedMem", "a.exe"); return b.exec(); }

关键设计要点

  1. 共享内存管理
    • 使用全局键Global\\MySharedMem确保跨进程访问
    • 自动处理共享内存的创建/连接逻辑
    • 使用lock/unlock保证数据一致性
  2. 进程控制
    • 通过QProcess实现进程生命周期管理
    • 支持跨平台(Windows/Linux)的进程终止
    • 添加错误处理回调
  3. 故障检测逻辑
    • 5秒周期读取共享内存
    • 单次数据未变化即触发重启
    • 状态计数器防止误触发
  4. 边界处理
    • uchar类型自动处理0-255循环
    • 进程终止超时处理(3秒等待)
    • 共享内存错误处理

部署与测试

  1. 编译配置

    • 在.pro文件中添加:

      makefile

      QT += core CONFIG += console c++11
  2. 运行顺序

    bash

    # 先启动监控程序B ./b # 后启动数据程序A ./a
  3. 测试场景

    • 正常情况:B每5秒读取到递增数值
    • 异常测试:手动终止A进程观察B是否自动重启
    • 压力测试:长时间运行验证稳定性

扩展优化建议

  1. 添加日志系统:使用QDebug或日志框架记录运行状态
  2. 增加心跳机制:在共享内存中添加时间戳
  3. 配置文件支持:通过配置文件设置共享内存键值和路径
  4. 多实例支持:通过参数化实现多数据源监控

此方案实现了严格的周期控制、可靠的进程管理和高效的共享内存通信,满足用户提出的所有技术要求,并具有良好的跨平台兼容性和可扩展性。

2.Global\\MySharedMem 是全局键的意思吗

是的,Global\\MySharedMemWindows 操作系统中确实是全局命名空间的共享内存键标识符,而在Linux/macOS 等类Unix系统中,Qt 会自动将其转换为标准的共享内存键(如通过文件路径或系统IPC键)。以下是详细解释:

1. Windows 平台下的全局键

  • Global\\前缀
    • 这是 Windows 特有的命名空间前缀,用于创建跨用户会话的共享内存(例如不同用户登录的会话、服务进程与用户进程间通信)。
    • 普通键(如MySharedMem)仅在当前用户会话内可见,而Global\\MySharedMem对所有会话可见。
    • 需要管理员权限或特殊权限才能创建全局命名对象。
  • 示例场景
    • 系统服务(运行在 Session 0)与用户界面程序(运行在 Session 1/2...)需要共享数据时,必须使用Global\\前缀。

2. Linux/macOS 平台下的处理

  • Qt 的跨平台抽象
    • Qt 的QSharedMemory自动转换键格式以适应不同操作系统:
      • Linux/macOS:使用标准的 POSIX 共享内存(如/dev/shm/MySharedMem或通过ftok生成的键)。
      • 键值唯一性:Qt 会确保同一键名在不同平台映射到唯一的系统资源。
  • 无特殊前缀需求
    • 在类Unix系统上,无需使用Global\\前缀。直接使用MySharedMem即可,Qt 会处理底层实现。

3. 键名设计的最佳实践

  • 跨平台兼容性
    • 推荐使用无前缀的键名(如MySharedMem),让 Qt 自动处理平台差异。
    • 若需强制全局可见(仅Windows),可保留Global\\前缀,但需测试权限和兼容性。
  • 避免冲突
    • 使用唯一且复杂的键名(如包含公司名、程序名、随机字符),例如:

      cpp

      QString sharedKey = "CompanyName_ProgramA_SharedMem_2025";
  • 权限控制
    • 在 Linux/macOS 上,确保进程对共享内存路径(如/dev/shm)有读写权限。
    • 在 Windows 上,若使用全局命名空间,需以管理员权限运行程序,或调整用户权限。

4. 验证键名行为(示例代码)

可通过以下代码验证不同平台下的键名解析:

cpp

#include <QSharedMemory> #include <QDebug> int main() { QSharedMemory shm("Global\\MySharedMem"); qDebug() << "Raw key:" << shm.key(); qDebug() << "Is attached?" << shm.isAttached(); #ifdef Q_OS_WIN qDebug() << "Running on Windows"; // 实际创建的是全局命名对象 #else qDebug() << "Running on Unix-like system"; // Qt 转换为标准共享内存路径 #endif return 0; }

5. 替代方案与扩展

  • 文件映射(Memory-Mapped File)
    • 使用QFileQFileDevice::map创建基于文件的共享内存,跨平台更一致。
  • Qt Remote Objects
    • 若需更复杂的跨进程通信,可考虑 Qt 的远程对象模块(QtRO)。
  • 系统级IPC
    • 如 Socket、DBus(Linux)或命名管道(Windows),适用于大数据量或高并发场景。

总结

  • Global\\是 Windows 特有的全局命名空间前缀,在类Unix系统上由 Qt 自动适配。
  • 跨平台开发时,建议使用无前缀的键名,并依赖 Qt 的抽象层处理差异。
  • 需注意权限和命名冲突问题,尤其在多用户/高安全场景中。

此设计确保了程序在 Windows 和类Unix系统上的兼容性,同时利用了 Qt 的跨平台优势。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/11 15:43:48

Kotaemon备份与恢复策略:防止数据丢失

Kotaemon备份与恢复策略&#xff1a;防止数据丢失 在构建企业级智能对话系统时&#xff0c;一个常被低估但至关重要的问题浮出水面&#xff1a;如何确保当服务重启、节点宕机或部署迁移后&#xff0c;用户的多轮对话不会“从头开始”&#xff0c;知识检索能力无需数小时重建&a…

作者头像 李华
网站建设 2026/7/12 10:19:08

批量将 Word 文档重命名为其标题

一、问题描述 在日常办公中&#xff0c;我们常遇到这样的情况&#xff1a; 公司通过某管理系统批量上传 Word 文档后&#xff0c;原始文件名被替换为一串无意义的编码&#xff08;如 aB3xK9.docx&#xff09;&#xff0c;导致文件难以识别和管理。 虽然系统提供文件预览功能&…

作者头像 李华
网站建设 2026/7/13 21:16:28

Kotaemon本地部署教程:保护数据隐私的新选择

Kotaemon本地部署教程&#xff1a;保护数据隐私的新选择 在金融、医疗和法律等行业&#xff0c;AI助手正变得不可或缺——它们能快速解答政策问题、辅助病历分析、生成合规文档。但一个现实难题始终困扰着企业&#xff1a;我们真的能把客户信息、内部流程甚至战略文件上传到云端…

作者头像 李华
网站建设 2026/7/12 23:18:33

Kotaemon支持GraphQL接口吗?现代API集成方案

Kotaemon 支持 GraphQL 接口吗&#xff1f;现代 API 集成方案 在构建智能对话系统时&#xff0c;我们常常面临一个现实挑战&#xff1a;用户的提问越来越复杂&#xff0c;涉及的数据来源也愈发多样。比如一位销售经理问&#xff1a;“上季度华东区哪个产品的利润率最高&#xf…

作者头像 李华
网站建设 2026/7/12 23:25:46

基于Kotaemon的政策法规智能查询系统

基于Kotaemon的政策法规智能查询系统 在政务大厅里&#xff0c;一位创业者反复翻阅十几份PDF文件&#xff0c;只为确认自己是否符合高新技术企业认定条件&#xff1b;而在后台&#xff0c;工作人员每天要重复回答上百次“小微企业有哪些税收优惠”这类问题。这种信息不对称与服…

作者头像 李华
网站建设 2026/7/13 5:06:05

Kotaemon前缀缓存机制:加速重复查询响应

Kotaemon前缀缓存机制&#xff1a;加速重复查询响应 在企业级智能问答系统日益普及的今天&#xff0c;一个看似简单的问题——“如何申请年假&#xff1f;”——可能每天被成百上千名员工反复提出。如果每次请求都让大模型从头开始推理&#xff0c;不仅浪费算力&#xff0c;还会…

作者头像 李华