Dining Philosophers in LabVIEW

History

As I program in LabVIEW I am surprised by the number of times small bits of code cause large problems.  For example, I was working with a large system that communicated with many instruments.  I made some changes, tried running the code, and the program locked up! My gut reaction was to blame the LabVIEW development environment or a driver, but in the end I discovered the code I changed caused the hang.

Dining Philosophers

I did finally find what was causing the hang, but it took a long time.  The hang was caused by two resources that were used by two different pieces of code (see the Wikipedia’s Dining Philosopher article for a good explanation of this).  Both pieces of code had one of the resources, but neither would relinquish the resource because they were waiting for the second resource.

This can be shown in LabVIEW with the following code:

Mutually locked resources 

So Don't do That

The above example is simple enough to be trivially avoided.  However, it can get more subtle.  Consider a non-Reentrant SubVI; a second caller to the subVI will block until the subVI finishes on the first caller.  This allows the same hang to occur with a subVI and a queue as shown below.  Note that there is a second queue shown which is not causing the hang, but is needed for the subVI to be called twice: 

Blocking subvis


Still Want to Use References?

The code I had written was fixed easily.   The code had started before Data Value References (DVRs) existed in LabVIEW, so it used a Queue with a single element as a referenced resource.  I made a change to the data dependency so that the Dequeue would happen later and not block the other code from executing.   The experience did make me a little more cautious, and I’m on a quest to find out how to avoid these mistakes in the future.  Here’s what I’ve got so far:

  • Use a message-based architecture to avoid sharing resources:  I know many are successful with message-based architectures like the actor framework.  I cringe at doing this myself.  It works, but it is trading one set of problems for another.
  • Use the “In Place Element Structure” instead of Queues for references.  The In Place Element Structure groups the data value read in the same structure as the data value write.  This means that the read won’t happen until all the inputs to the structure are ready.  The Dequeue function in the example above happens before all the inputs are ready for the Enqueue function, and that allows the hang to occur.
  • Consider setting VI executions to reentrant.  When creating a new VI, the default is non-reentrant.  If a VI is non-reentrant, it is a resource that must be shared and it may block.
  • Be especially wary of code that must wait for multiple resources to be available.  For such code, see the “Dining Philosophers” link for ways to address the lockup issue.


The Good News

References are an intuitive way to program, and they are used frequently in LabVIEW.  Consider all the references in LabVIEW:

  • Synchronization VIs: DVRs, Queues, Notifiers, etc.
  • VI Server: VI References, Control References, etc.
  • Driver APIs: DAQ Tasks, VISA Resources, FPGA References, etc.
  • Computer Resources: File References, TCP Refnum, etc.
  • Many, many others…

You will use many references as you program in LabVIEW.  You may even start to use references in your APIs as I do.  If you have advice or a story about references locking up code, I’d love to hear it!  

Shawn Walpole

Senior Systems Engineer

Shawn Walpole started programming with Microsoft Basic on the Apple Macintosh 128k computer in the 1980s and has loved it ever since. He graduated with a Mechanical Engineering BS degree and a Computer Science minor from the University of Utah in 2000. He worked on the LabVIEW R&D team at National Instruments for four years developing LabVIEW before moving to Moore Good Ideas. Shawn was impressed by Endigit's vision and joined the Endigit team in 2014.

Shawn gets job satisfaction out of meeting customer needs. He likes LabVIEW because well-written code is easy to read and because of the power of a development environment that was written for programmers working with real hardware.

Shawn has industry experience programming LabVIEW and C/C++. He has worked with Real Time, FPGA, DAQmx, Motion, TestStand, and Veristand.

Add new comment