I have created this feature to create named variables of any data type in memory and access its value from any part of data code which is under same scope using its name.
This variables stores instantaneous value.
Once variables are created in memory, you can be grouped them and access its values using names.
You can create variable for any data datatype & access its value using its Name.
Please check and let me know your suggestions.
use LabVIEW 15 sp1
I have asked a moderator to move this post to the regular LabVIEW forums since it is not a request from you for NI to add functionality to LabVIEW but is instead a toolkit using LabVIEW's existing functionality.
I opened up the toolkit and poked around.
The toolkit looks good from a pure coding standpoint. But I'm concerned about its functionality. I would recommend that you and everyone else avoid programming G this way.
I hate raining on my own customers' successes, especially one that clearly shows so much good architecture and thought. I need to do so, however, in order to prevent this kind of unsafe programming from growing more prevalent and hurting the LabVIEW ecosystem.
What you have built is something that NI has declined to build explicitly repeatedly over the years because it is very dangerous: likely to cause unexpected and unrepeatable failures in running applications, even ones that have passed well-written test suites repeatedly. "Globally-defined variables with no read-modify-write locking protection in an inherently parallel environment" is a recipe for disaster in most applications. We know this not just from LabVIEW but from lots of other programming languages.
Consider this code:
These two loops perform a read-modify-write in parallel on four variables. You, the toolkit author, may be aware of the problems with doing this, but many users are not, no matter how often they are taught. We see this sort of thing done with local and global variables regularly. Many programmers would expect
But this is the output of the program from one run. Every time I run it, I get different results:
That's because the iterations of the two loops are not "atomic" -- the operations of one are intermixed in time with the operations of the other. Because they are operating on by-reference data, they can sometimes (often) read the same value, both increment to the same new values, and then write back the same result. But a skew in how long it takes to read all four variables can cause some variables to increment more than others.
By reference programming with an unlocked read-modify-write nomenclature is very bad idea. That is why you cannot write this kind of code with LabVIEW's data value reference data types. And global lookup makes it even harder to control where in your program the data is accessed, which is NI does not put names on DVRs.
LabVIEW is a Turing-complete programming language, so you can write any code that you could write in any other language using it. That includes the bad ideas. I am sorry, but this is one of the bad ideas. Yes, you can write successful programs with this style, but many programmers in many languages will tell you that it is unsafe, and extremely hard to be sure that you're controlling the references correctly. LabVIEW provides much better tools for data communication than a raw, globally named variable.
I would not recommend that anyone program G this way.
Thank you very much for your time & analysis. 🙂
I designed this tool taking consideration of data acquisition & display instantaneous value.
In this case, Only data acquisition loop will set values of variables.
And whenever we want to read & use this value we can do.
Find following example for your reference. Above loop acquire data from HW & below loop is used for display purpose. May be we need to limit write functionality to only acquisition(write) loop.
I hoped that data acquisition was your main use case. But if that's your use case, why not use a queue or notifier refnum directly? Queues avoid the read/modify/write problem. Notifiers very closely match what you're doing but they discourage the read/modify/write problem because of their terminology and signaling pattern. They will also be more performant because they'll avoid some of the data copying that your variables introduce. What advantage are your variables adding over those built-in tools?
FYI in case the OP has not come across them, similar "variable creation" packages include "Tag Bus Library" and older "Current Value Table" by NI, and "VIregisters" by "GPower".
Though, like AQ, I don't recommend using any such features and instead only use messages.
I have tried to put similar messages out for those tools as well. Doesn't earn me a lot of love with some of the hardware teams who really like their variables dynamic, named, and global. 🙂
Why not use a queue or notifier refnum directly?
- If we use queue or notifier directly, then we have to code it every time, I just provided this API's to ease of programming. We can achieve read-modify-write functionality, if we use Queue. but it will results into blocking call. this implementation for 1:1 or 1:N variable access.
What advantage are your variables adding over those built-in tools?
- I provided this API's for easy to use while programming. Also we can create multiple groups so that it will be easy for access & light weight.
"Tag Bus Library" and older "Current Value Table" by NI, and "VIregisters" by "GPower".
- "Tag Bus Library" & "CVT" Uses FGV, so its blocking call for application.
- I think queues much faster and more lightweight on memory (queues vs. FG-VI), and each variable has its own non-blocking queue vs. a blocking FG per data type in CVT.
- "VI Registers" by GPower also stores all references Shift registers, use command/response functionality & use searching method to read & write variable, where as in my API it will directly access queue reference and read variable. This will reduce latency to read & write.
Note that this API's used for 1:N 1:1 variable access.
Please let me know if you have any suggestions.