labview 运行底层是 Labview 运行时,因此所有vi、while循环都是以子线程形式运行,依靠run time ,可以共享资源,如通过队列、通知器在线程间传递消息。
队列使用
线程间队列消息传递示例1 传递队列引用
- 1 新建N

- 2 选择生产者/消费者设计模式(事件)
2
建立工程如下: 下图中在循环开始前创建队列引用,并将队列引用传递给两个while循环,


通过事件条件结构,在事件触发时,将元素加入队列中,在消费者循环中每周期对队列进行一次出队列操作,获取队列元素。
程序停止说明
labview程序退出不能依靠点击右上角叉号或点击工具面板的中止执行。程序停止需要释放资源:队列引用、关闭调用的子VI等。
上例中当点击stop按钮(stop值改变),在生产者循环中先停止while,随后释放引用。引用被释放后,消费者循环的出队列函数将会报错,从而停止循环。

线程间队列消息传递示例2 传递队列名称


程序开始时,通过名称:MainQueue创建队列引用并将Init加入队列,注意此时未向循环传递队列引用,只通过簇2传递了队列名:MainQueue。

此处生产者循环在触发事件时,根据队列名称将元素加入队列,图中白色VI:

在子线程内根据队列名称出队列:

本例通过 队列名-获取队列引用 方式 在不同线程间访问同一队列
注意
除创建引用外,使用 获取队列引用函数 时 后面必须释放引用,不然每次创建一个单独的引用。 可以看到上图中通过名称获取引用------出队列------释放引用。
当引用数量未知:可通过 释放引用函数(强制销毁=True)即可。
通知器
故障停机 非常适合用 Notifier,但要用"正确方式"。**
一、为什么"故障停机"适合 Notifier?
故障停机的本质通常是:
- ❌ 不需要每一条历史故障
- ❌ 不需要顺序
- ✅ 只需要"发生过故障"这个事实
- ✅ 要立刻唤醒所有线程
- ✅ 重复触发也没意义
👉 这和 Notifier 的语义完全一致:
| 故障停机需求 | Notifier 特性 |
|---|---|
| 广播给所有模块 | 唤醒所有 Wait 线程 |
| 只关心最新状态 | 只保存最后一次值 |
| 立即响应 | Wait 阻塞 → 立刻唤醒 |
| 不关心次数 | 覆盖旧值 |
二、最推荐的故障停机模型(工程级)
🔴 模型:状态型 Notifier
Notifier 里传什么?
-
一个 枚举 / Cluster
OKFAULTSTOP
📐 结构(文字版)
初始化(只做一次)
Obtain Notifier → Notifier Refnum
各工作线程
While Running:
Wait on Notification (timeout = -1)
IF 状态 == FAULT or STOP:
安全退出
故障检测线程
检测到故障 →
Send Notification (FAULT)
🔑 为什么这样"不会丢消息"?
-
即使某个线程:
- 还没开始 Wait
- 或刚好在忙
-
下一次它调用
Wait on Notification- 立刻会拿到 FAULT
-
因为 Notifier 内部保存的是"最后一次状态"
👉 非常适合"停机"这种一次性状态
三、常见错误用法(⚠️ 很多人会踩)
❌ 错误 1:把 Notifier 当 Queue 用
Send FAULT1
Send FAULT2
Send FAULT3
👉 接收者只看到最后一个
✔️ 正确:
故障停机只发一次
FAULT
❌ 错误 2:每个线程自己 Obtain Notifier
👉 这样拿到的不是同一个 Notifier
✔️ 正确:
只 Obtain 一次,通过 Refnum 传递
❌ 错误 3:故障后立刻 Release Notifier
👉 有些线程可能还没 Wait
✔️ 正确:
等所有线程退出后,再 Release
四、什么时候 Notifier 不够用?
❌ 以下情况不适合单独用 Notifier
- 需要记录多条故障
- 需要区分故障来源
- 需要故障确认 / 应答
- 需要顺序处理
👉 这些情况:
Queue(故障日志) + Notifier(停机广播)
是工程里最常见、最稳妥的组合。
五、一句话总结(请记住)
故障停机 = 状态广播 → 用 Notifier 最合适;
它保证"所有线程最终都会知道已经故障",而不是"知道每一次故障发生"。
如果你愿意,我可以帮你:
- 设计一个 完整的"故障停机 + 多线程退出"架构
- 或对比 Notifier vs Queue 在停机逻辑上的差异图
你更想看哪一个?