LabVIEW Actor Framework: Structured Concurrency for Scalable Test Systems
Actor Framework replaces shared-variable race conditions with message-driven actors. Here's when to adopt it, a temperature-monitor example, and the overhead you'll pay.
13 Jul 2026, 17:30 UTC

The Problem: Shared Variables Don't Scale
LabVIEW developers often start with Queued Message Handlers (QMH) or shared variables for inter-loop communication. As channel counts grow, race conditions appear, debugging becomes a probe‑maze, and adding a new hardware module means rewiring half the block diagram. The Actor Framework (AF) ships with LabVIEW Professional/Full Development System (2012 SP1+) to address exactly this: it enforces asynchronous, message‑only communication between independent actors, each owning its private state in a shift register inside Actor Core.vi.
Core Concepts in Three Classes
- Actor.lvclass – abstract base; override
Actor Core.vito define the message‑processing loop. - Message.lvclass – abstract base; each concrete message (e.g.,
SetSampleRate.msg) overridesDo.vito implement its action on the actor's private data. - Launch Actor.vi – starts an actor in its own VI Server context, returning an enqueuer (actor reference) for sending messages.
Actors never share memory; they communicate only by enqueuing message objects. This eliminates the classic "read‑modify‑write" race on global or shared variables.
Worked Example: Temperature‑Monitoring System
Consider a system that reads a thermocouple at 10 Hz, displays a waveform chart, and logs batches of 10 readings to TDMS. The project TemperatureMonitor.lvproj contains three actors started by a Launcher:
- Hardware Actor – wraps NI‑DAQmx. Its
Actor Core.viruns a timed loop (100 ms), reads the channel, and sends aTemperatureReading.msg(carrying a double) to both the UI and Logger actors. - UI Actor – uses an event structure to update a waveform chart on the front panel. It registers for
TemperatureReading.msgat launch. - Logger Actor – accumulates readings in a shift‑register array; when the count reaches 10, it writes a TDMS segment and resets the buffer.
Changing the sample rate requires only a new SetSampleRate.msg class with a Do.vi that updates the Hardware actor's loop timer. No wiring changes in the Launcher or other actors.
// Pseudo‑code for SetSampleRate.msg Do.vi override
method Do.vi (Actor Core.vi's private data cluster)
// private data includes "Sample Rate (ms)" element
Private Data.Sample Rate (ms) = Input Sample Rate
// reconfigure timed loop or wait time
end method
Trade‑offs and Limitations
| Aspect | Impact |
|---|---|
| Memory/CPU overhead | ~5–10% vs. flat QMH (measured with Windows Performance Analyzer on equivalent builds). |
| Learning curve | Requires comfort with by‑reference OOP, class inheritance, and asynchronous design. |
| Debugging | Asynchronous flows need Actor Framework Debugger Toolkit (separate install) or Probe Watchpoints on Actor Core.vi. |
| Edition requirement | Not installed in LabVIEW Base/Standard; Professional or Full Development System required. |
| Heavy computation in Do.vi | Can starve other actors – offload to Timed Loops, .NET/CLI nodes, or a dedicated compute actor. |
| WebVI deployment | Actor Framework runs only on the server (LabVIEW 2020+); browser clients use WebSocket messages, not native AF. |
Migration Path and Deployment
Existing QMH modules can be refactored incrementally:
- Wrap the QMH loop in
Actor Core.vi. - Convert enum‑based messages to concrete
Message.lvclasssubclasses. - Replace
Dequeue ElementwithReceive Message.vi.
For deployment, build each actor as a Packed Project Library (PPL). PPLs enable independent versioning and reuse across Windows executables, RT targets, and WebVI servers. Distribute actor PPLs via NI Package Manager feeds so a top‑level project can depend on HardwareActor.vip and LoggerActor.vip without relinking when one actor is rebuilt.
Actionable Next Steps
- Open LabVIEW 2023 Q3 (or later), create a blank project, right‑click My Computer → New → Actor Framework Template to verify installation and inspect the starter classes.
- Run the shipped example:
<LabVIEW>\examples\Actor Framework\Actor Framework.lvproj. Launch it and probeActor Core.vito observe message handling. - Build a minimal QMH and an equivalent AF version (e.g., a single DAQmx read loop). Deploy both to a Windows target and compare memory/CPU with Windows Performance Analyzer.
- If the overhead is acceptable and your team can invest in the OOP learning curve, start a new module as an actor and package it as a PPL for reuse.
Actor Framework isn't a silver bullet, but for systems that outgrow QMH's wiring complexity, it provides a disciplined, scalable architecture with clear ownership boundaries.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.