07-13-2023 11:05 AM
Hi,
I have a VI MAIN that calls 4 parallel subVIs. All of this subVIs have access to a global variable called "array" (i.e. array of 4 booleans) that is in VI MAIN.
I have implemented the code in order to have the 4 subVIs as multiple writers of the global variable. In particular, each subVI has to change his corresponding boolean value of array. For example: subVI 1 has to change only the 1st boolean of array but no others. SubVI 2 has to change the 2nd boolean of array and so on.
Although I've found some problems. When i try to set the array as 1-0-0-0 from subVI 1, Global variable in MAIN VI reads an array that has an intermittent 1st value.
in according to me the problem is that when subVI 1 writes the 1st boolean value as 1 (ON), the other 3 subVIs write 0 (OFF) on the same boolean value in the array.
Essentially i think is a problem of "multiple writers on a single variable"
How can i solve this problem? Which is the best solution?
Thank you!
Solved! Go to Solution.
07-13-2023 11:32 AM
Classic race condition. Whoever wrote to the global last will show up when the global is read. What exactly are you trying to accomplish here? I'm not understanding your actual goal.
07-14-2023 04:42 AM
I would to have the last written value in the global, but the problem is that the value in the global swing between the value written by the subVIs.
The goal of the application is to have 4 parallel writer of the same global variable in a right manner.
for example the problem is that when subVI 1 writes the 1st boolean value as 1 (ON), the other 3 subVIs write 0 (OFF) on the same boolean value in the array at the same time.
I don't understand how solve this problem.
07-14-2023 04:53 AM
Hi tj,
@tj1995 wrote:
I don't understand how solve this problem.
You created a shared resource with your global variable. Now you have to limit the access to this shared resource…
One way would be to use a FunctionalGlobalVariable (FGV, aka AE=ActionEngine), which holds the value in it's internal shift register. As the FGV is set to "non reentrant" (default for subVIs) it will enforce "atomic" operations, several callers of that FGV will NOT execute at the same time.
You provide an API consisting of an enum input (to provide a "command") and a value input: each call of the FGV follows the scheme of cmd="set value x" to "value". Possible commands in your case include "init", "set value x", "read value x", "read all values"…
Using FGVs might help for single items, but is not very scalable. There are other ways to encapsulate data access, one of them involves using OOP practices…
07-14-2023 06:45 AM
@tj1995 wrote:
The goal of the application is to have 4 parallel writer of the same global variable in a right manner.
for example the problem is that when subVI 1 writes the 1st boolean value as 1 (ON), the other 3 subVIs write 0 (OFF) on the same boolean value in the array at the same time.
It sounds like you need to limit when the variable is written in the subVIs. Are they also supposed to get an update (ie update their control when another subVI updates the control)?
07-14-2023 06:46 AM
There are many ways to do things in LabVIEW and you will get many good suggestions.
You can make the Global method work if you restrict each clone to access only it's element in the array.
I've modified your example - see if it works for you.
07-15-2023 01:32 AM
@stevem181 wrote:
There are many ways to do things in LabVIEW and you will get many good suggestions.
You can make the Global method work if you restrict each clone to access only it's element in the array.
I've modified your example - see if it works for you.
This is still a glaring race condition because each clone does a <read global...modify one element...write global> and since the global is not locked during modification, things can cross-talk. In the most extreme case, all clones read in quick successions, each modify their element in parallel, but once all write back, only the last one wins. It needs to be encapsulated on a non-reentrant action engine to prevent that.
07-15-2023 01:39 AM
@altenbach wrote:
It needs to be encapsulated on a non-reentrant action engine to prevent that.
A primitive draft:
You want to add more modes (init to set size, read, write, clear, etc.).
07-17-2023 02:32 AM
I have tried in this way and it's perfect!
Thank you!
07-17-2023 03:51 AM
@tj1995 wrote:
I have tried in this way and it's perfect!
Which way?
(We cannot the which post you are replying to, but it seems you marked a solution. Did you read my later post explaining that the currently marked solution still has a glaring and dangerous race condition?)