看门狗(WatchDog)自动退出管理
CSM WatchDog是一个内置插件,用于在主程序退出后,自动通知所有异步启动的CSM模块正常退出,避免孤儿模块残留。
WatchDog 只负责管理异步启动的CSM模块。同步调用的模块必须由调用方自行管理退出:同步调用的模块若不退出,调用它的VI就无法继续执行后续代码退出,主程序VI就无法退出,WatchDog Queue也就不会被释放,退出流程也就不会被触发。
功能说明
问题背景
在CSM应用中,各功能模块通常以异步方式独立启动。主程序VI可以主动向它负责管理的模块发送 Macro: Exit 消息,让它们有序退出。然而,当程序结构复杂时,难免会有一些模块没有被主程序主动通知退出——WatchDog的职责就是接管这些遗留的、尚未退出的模块,在主程序VI退出后将它们统一清理。
这正是”WatchDog(看门狗)”名称的由来:它在后台持续监视,当主程序退出后,对所有还在运行的异步CSM模块发出退出指令,确保没有模块被遗忘。
实现原理
CSM WatchDog实现的原理
LabVIEW VI退出时,会自动释放所有队列、事件等句柄资源。因此,WatchDog通过创建一个专用的队列资源,由主程序VI持有该队列的引用。这个队列资源会随着创建主VI的退出而被LabVIEW自动回收,从而触发后台监控线程退出并广播
Macro: Exit:
- 主程序运行时,队列存在,WatchDog保持等待;
- 主程序VI退出前,可主动向自己管理的模块发送
Macro: Exit,让它们有序退出;- 主程序VI退出时,LabVIEW自动回收队列资源;
- WatchDog检测到队列已回收,立即向所有尚未退出的CSM模块广播
Macro: Exit,清理遗留模块。
WatchDog与主程序的主动退出管理互为补充:主程序可以主动管理其负责的模块,WatchDog负责兜底处理未被显式退出的遗留模块。
sequenceDiagram
participant Main as 主程序 VI
participant WD as WatchDog 线程
participant M1 as CSM 模块 1
participant M2 as CSM 模块 2
participant M3 as CSM 模块 3(遗留)
Main->>WD: CSM - Start Watchdog to Ensure All Modules Exit.vi<br/>(创建队列并启动WatchDog线程)
Main->>M1: 异步启动
Main->>M2: 异步启动
Main->>M3: 异步启动
Note over Main: 程序正常运行...
Main->>M1: 主动发送 Macro: Exit(主程序自行管理)
Main->>M2: 主动发送 Macro: Exit(主程序自行管理)
M1-->>M1: 正常退出
M2-->>M2: 正常退出
Main-->>Main: VI 退出,LabVIEW 自动回收队列
WD->>WD: 检测到队列已回收
WD->>M3: 广播 Macro: Exit(接管遗留模块)
M3-->>M3: 正常退出
函数说明
API 一览
| 函数名 | 功能 | 调用时机 |
|---|---|---|
CSM - Start Watchdog to Ensure All Modules Exit.vi | 启动WatchDog监控线程,返回Watchdog Queue引用 | 主程序初始化阶段,尽早调用 |
CSM - Start Watchdog to Ensure All Modules Exit.vi
启动CSM WatchDog后台线程,用于监控主程序是否退出。一般在主程序启动后立即调用。
输出控件:
- Watchdog Queue:WatchDog监控队列引用。通常保持连接(连接到移位寄存器或局部变量)直至主程序VI结束,让LabVIEW随VI退出自动回收;如果明确知道要提前触发退出流程,也可以手动释放该队列引用,同样会激活WatchDog退出机制。
调用逻辑
flowchart TD
A[主程序启动] --> B["调用 CSM - Start Watchdog to Ensure All Modules Exit.vi"]
B --> C[获得 Watchdog Queue 引用]
C --> D[保持 Watchdog Queue 引用\n(移位寄存器/局部变量)]
D --> E[异步启动各 CSM 模块]
E --> F{程序运行中}
F -->|继续运行| F
F -->|开始退出| G[主程序主动向自行管理的模块发送 Macro: Exit]
G --> H[主程序 VI 退出\nLabVIEW 自动回收 Watchdog Queue]
H --> I[WatchDog 线程检测到队列已回收]
I --> J["广播 Macro: Exit 给所有尚未退出的 CSM 模块(遗留模块)"]
J --> K[所有模块正常退出]
典型应用场景
典型场景:嵌入式/仪器控制应用
在仪器控制场景下,各硬件模块(DAQ、串口、GPIB等)通常以异步CSM模块运行。主程序在退出前可主动通知关键硬件模块释放资源,WatchDog则确保任何未被主动通知的模块也能正确退出,避免仪器资源被锁定。
// 主控程序
Initialize >> {
CSM - Start Watchdog to Ensure All Modules Exit.vi
→ Watchdog Queue
// 异步启动硬件模块
Run Async: DAQModule // 数据采集模块
Run Async: SerialModule // 串口通信模块
Run Async: DisplayModule // 显示模块
}
// 退出时:
// 1. 主程序主动通知 DAQModule 停止采集并退出(主程序自行管理)
// 2. 主程序 VI 退出,LabVIEW 自动回收 Watchdog Queue
// 3. WatchDog 接管 SerialModule 和 DisplayModule,广播 Macro: Exit
// 4. 所有硬件模块正确释放资源后退出
注意事项
- 仅管理异步模块:WatchDog只会向异步启动的CSM模块发送
Macro: Exit。同步调用的模块不在WatchDog管理范围内,需调用方自行确保其退出。- 尽早调用:在主程序初始化阶段(异步启动其他模块之前)调用,确保WatchDog在所有模块启动之前就已就绪。
- 每个主程序只需调用一次:多次调用会启动多个WatchDog线程,造成重复发送退出命令。
- Watchdog Queue的释放:通常让LabVIEW随主程序VI退出自动回收;如果需要提前触发退出流程,也可以手动释放该队列引用。