Blog

How to Share Data and Mutexes in LabVIEW 2

In the previous installment of this blog series we learned how the way in which we architect our applications can influence execution time: either allowing VIs to execute faster OR causing a VI to execute slower due to blocking.  In this installment, we will cover methods to allow sharing data between parallel processes as well as their pros and cons. Example source code included!

In LabVIEW, data can be shared by reference or by value:

When data is shared by value, a copy of the data is made available to any sources that would like to use it.  This copy is unique and in no way (other than the value it contains) linked to the source of the data.  No blocking occurs when data is shared by value.

share_by_value.png

When data is shared by reference, any sources that want to access the data must access the same memory location to get the ‘value’ of the data.  Some methods to access data by reference will block (such as Data Value References) by default, while others won’t block, but may not return the most current data (Notifiers).

share_by_reference_2.png

Sharing data via value provides the highest execution speed but as data is not stored in a common location, challenges can arise when data needs to be modified AND that modified data needs to be shared/updated.

Sharing data via reference provides the greatest architectural flexibility in that you are not limited by how your VIs are executing or their proximity to each other.  Unfortunately, LabVIEW best practices would require some method of arbitration (e.g. functional global) which may block and reduce execution time noticeably.

I’ve included three examples of an implementation of a very simple Bank: one using local variables, one using shift registers and another using a functional global.

VI Snippet of Bank implemented using local variables

Using local variables to store the value of balance isn’t protected from read/write operations so there is a high possibility of a read/write/modify race condition. This can affect the function of the ‘bank’ where if a deposit and withdrawal are made simultaneously, the balance may not be correct.

VI Snippet of Bank implemented using shift registers

Using shift registers to store the value of balance limits your architecture (e.g. performing a withdrawal outside the while loop), but eliminates the read/modify/write race condition in doing so. Any future additions that use or modify balance, must be contained within the while loop/event structure. In addition, this implementation of the bank cannot have truly simultaneous transactions.

VI Snippet of Bank implemented using functional global

Using a functional global to store the value of balance protects each individual operation so there is no possibility where a deposit and withdrawal happening simultaneously will create an incorrect balance.

The source code for the bank examples can be found here. In the final installment of this series, we will learn how to create a solution to get the best of both worlds and optimize our execution time while still being able to maintain our architectural flexibility by sharing data by reference.

Recent Posts:

Failure Analysis: Is it Important?
Publish Date 08 Aug 2017 Nathan SzantoAntonio Alexander

Yes.

Communication Through Design - Making Assembly Easier
Publish Date 08 Aug 2017 Garret HallmarkAntonio Alexander

After dozens of hours designing an assembly and weeks of waiting for parts to [..]

The Virtual Water Cooler

We have all experienced many changes to our daily lives over the past few months. [..]

Implementing OAuth2 Authorization in LabVIEW
Publish Date 08 Aug 2017 John AmstadtAntonio Alexander

  What is OAuth2?

Oil and Gas from a Sales Perspective

I have been fortunate enough to work in the oil and gas industry for over a year [..]

4 Simple Rules to Write Clean Code
Publish Date 08 Aug 2017 Yifang YangAntonio Alexander

  Computer code may seem structured and sterile. But, like any skill there is an art [..]

Popular Posts

Posts by Topic

See All Topic