-
Posts
3,183 -
Joined
-
Last visited
-
Days Won
202
Content Type
Profiles
Forums
Downloads
Gallery
Posts posted by Aristos Queue
-
-
- Popular Post
- Popular Post
A friend pointed me to a website dedicated to restoring rare words to common usage. The site randomly picks a word for each visitor to popularize. I got two, and both of them are excellent choices for me since I have a use for both of them. The one that I encourage LabVIEW users to adopt is:
primifluous: that which flows first.
As in: "The primifluous wines were excellent."
For LabVIEW and dataflow, the usage is obvious: "The primifluous nodes initialize the hardware." "Perhaps you should make that assertion primifluous.""FP Terminals are primifluous unless placed inside a structure node."
(The other word, in case you're interested, is "nidifice", and older term for an eagle's nest. Pronounced with "nigh" at the beginning and rhymes with "edifice". Given that NI's mascot is Nigel the Eagle, and that this term begins with "ni", I will henceforth refer to NI headquarters building as The Nidifice.)
-
4
-
I posted List and Tree a while back: http://lavag.org/top...classes-for-85/
It becomes unstable around 1000 elements because it relies upon recursion. The DVR solution is much more complex and has the weirdness involved with references, but can go much deeper.
Note that a list of 1000 elements is pretty poor... but a tree of depth 1000 is 2^1000 elements, which should be more than enough. :-)
-
Neil: that's exactly what I would suggest -- with the option to replace "user event" with other com techs such as queues or notifiers, as needed in your code.
Actor Framework would just make both the outer host VI and the inner subpanel VI be actors and then communicate the stop message through the queues.
-
I prefer to just disable the X using the VI Properties... less code on diagram to have to worry about. And the user doesn't have a useless [X] button to keep clicking on that doesn't do anything. Unless, of course, you're going to actually add code so that the [X] button causes Exit.
-
1
-
-
The first time this came up, the only thing I replied to was the factual error -- I'm tired of that garbage collector myth being propagated.
What I avoided was any commentary on the main post because I didn't feel like it, but today, I feel like asking:
Why do your objects have lifetime? Processes (VIs and communications channels) have lifetime. Data does not. These patterns that you're developing in your code come about because of the co-joining of these two concepts, an artifact of other programming languages that are piss poor programming models for a parallel environment.
-
1
-
-
Never break this rule: If an XControl or its member VIs knows about a class in any way shape or form, then that class must not know anything about the XControl except for (optionally) listing the XControl as a friend. You must avoid creating a circle of load dependencies. The easy way to test this is
1) In an empty project, load the XControl.
2) In a second empty project, load the class.
3) Look at the Dependencies section for both projects. If both projects list the other file as a Dependency, then you have a cycle.
Do not use the XControl on the panels of the class member VIs. Do not use property nodes of the XControls on the diagrams of the class member VIs. The only thing that your class *might* want to do is add its XControl as a friend and then put some utility VIs in the community scope. Violations of this rule inevitably lead to a crash of LabVIEW. I'm not proud of that fact. Fixing this crash would require us to design XControls completely differently from the ground up, and it just isn't likely to be fixed. Having said that, the crash does enforce the really good design principle of your data type knowing nothing of its display. So there is, I guess, a silver lining to the crash.
Now, assuming you follow that rule,
> What should/could I put in B's private data member ? an array of As ? an array of references to As ?
An array of As seems most appropriate. References? Who taught you about those? Ick! :-)
> What should/could I use as my xControls data type ? The natural answer is the same type as the class I wish to assaciate it with, but somehow I wonder if it can work in this case ?
The class. Assuming you follow the rules above, it works great. Build the class completely independent of the display, make it work, then build a display that let's users manipulate it.
-
It means a LabVIEW developer momentarily forgot that his/her users were not C++ programmers, the tech writer was on vacation, and this was written so long ago that when I asked if we could change it, the answer I got was, "No, that's the label of the terminal, which means someone might be using it in scripting code, and you'll break their code if you change it now."Can anyone answer the question: What does "*(type *) &x" mean?
That one doesn't count. That's an IEEE standard definition of the numerical value of Not A Number. That's correct as it stands, not a C++-ism that should have been scrubbed back in the dawn of LabVIEW.NaN - not a number
At least he's not drinking tonight. "Two beds and a coffee machine..."I hate it when mom and dad fight...
** Hah! Take that stupid editor. Try to inline my media files when I don't want you to... grrr...
-
Good read. I added this link to the Actor Framework community page.
-
Glad we were helpful.
-
And thank you for your patience.
-
Asbo: You miss the point... these are cases where you *don't care* whether the enqueue succeeds or not. Things such as "I am a task that fires this event if there's someone listening... if there's no one listening anymore, I keep doing my work." Literally, you don't want *any* notification if the thing fails. That's almost always the reason that I see "Not A Refnum" included in people's code.
-
ShaunR: The AE solution doesn't provide any protection against the race condition I originally posted about as long as the refnum is shared anywhere else... you'd have to encapsulate all operations on the refnum within the AE.
Because, in general, the whole point of "check if the refnum is valid and only do the operation if it is valid" is from use cases where you don't want an error if the refnum is invalid. So doing the op but ignoring the error gets you that effect.I'm a bit confused on AQ's second "Good usage"... why throw away the error, rather than just handling it downstream?
-
Austin:
Populating the user.lib palette is indeed as simple as saving into the user.lib directory. However, if by "creating a user library" you mean creating a distribution package for sharing your VIs with other people, then jgcode is right: VI Package Manager is your best tool for packaging and distributing a block of VIs... and, yes, there is a free version that does the basics that will probably suffice for you.
As for the controls in the palettes... Tools >> Advanced >> Edit Palette Set...
That will launch the palette editor. Create a new palette in the front panel palette (by right clicking) and then set it to sync a particular directory on disk. Any controls you save to that directory will be picked up the next time you restart LV.
-
Nope. It would make it just as likely... the structure node could not hold the lock on the refnum because you're using nodes that need to be able to lock the refnum inside the structure node. Even if you taught the nodes to recognize when they are directly within a structure node AND the refnum they're given is the one that the structure node is locking, it wouldn't help if the nodes were in a subVI inside that structure node.Cross link from the Idea Exchange:
http://forums.ni.com...r/idi-p/1022833
Would the implementation of this idea make this situation less likely?
Ultimately, this is the problem with references and is why I push so hard against being able to wire a reference directly to a by value terminal for method invocation. Without a single function that checks "is valid and if so do the operation" atomically, there's a race condition. If I write a by value class that has methods "Is Initialized" and "Do Something", wiring a reference to those two functions in sequence is incorrect usage. Whoever writes the reference API needs to build a single VI that locks the reference once and then does both of those operations before unlocking. These sorts of race conditions become ubiquitous very quickly and they're nearly impossible to debug. Heck... half the time I can't even convince people they have a bug because "it works just fine when I test it." And it will... until you've deployed it on your largest customer's end system. And then it will mysteriously fail.
Your time will vary depending upon the type of the refnum. Some types of refnums take longer to validate than others, depending on what system is used for the backing store for that refnum type and, in some cases, how many refnums are in memory. Also, some plug-in type refnums may require calling into a DLL using the UI Thread, so there could be a thread swap. Finally, the "equals not a refnum" test is deterministic, whereas the other test is not.Not A Refnum took 39 ms while Is Equal took ~1 ms. So yeah, Not A Refnum definitely takes significantly longer. But Not A Refnum still only takes ~150 nanoseconds per call, so is it worth worrying about? Perhaps if you're running in a really tight loop, but I have to admit I'm rarely concerned about a time hit that small. -
No. There are some experiments that I have to keep from escaping the lab.Sounds fun. Can you share what the nodes are/were?
No. :-)Do they involve registering, unregistering, and mapping values??
-
(Besides, are you *positive* nobody will ever want to register a value of zero?)
Actually, I do expect people to register zero... but zero and unregister are functionally equivalent.
-
-
Todd: Bingo. Those names don't imply "if I use one, I'll use the other." But I'm kind of afraid that Register and Unregister do. But I really like the verb in this particular context.
-
- Popular Post
- Popular Post
Just so everyone is clear:
Using the Not A Refnum function to decide to create a refnum is ok because the zero refnum cannot be destroyed/released in a parallel thread. But since the primitive does the extra work of validating the refnum, you take a performance hit on the cases that are going to succeed. Using the Not A Refnum function to decide to do an action or not is a race condition because a parallel thread could be destroying that refnum in between the test and the action.
If you need to actually do an operation, do one of these:
If you need the combined behavior of "if the refnum is bad, allocate it, and do some operation on it", then do this:
What is an acceptable use case for the Not A Refnum primitive?
- When you're evaluating the status of one refnum before taking an action on another refnum!
- Or if you're just displaying information in a Custom Probe.
- Or if you have absolutely nothing happening in parallel (in which case, you might reconsider your use of references anyway).
(For advanced users who suggest the use of semaphores to protect the access, that counts only as an OK usage because you still have a performance hit of unlocking and locking the refnum twice.)
If you ever are tempted to file a bug report that the LabVIEW queue functions are broken, please check your use of Not A Refnum first. I guarantee I will when the bug report gets to me. 🙂
And, for the record, all of the above also applies to using "Get Queue Status" and "Get Notifier Status" functions. And any other similar "is this refnum still valid" functions that you are using to make decisions in code.
-
7
-
I have functionality where I want to fill in a table that maps one value to another value. I have named the function that adds to this table Register XYZ.vi (where XYZ is my key type). I have a second function Unregister XYZ.vi that removes a key from the table.
Register and Unregister, however, create an expectation in LabVIEW that if a user of my API calls Register that somewhere in the code he or she should call Unregister for good coding practice. But I do not expect that to be the common case. There's no need to do an Unregister the vast majority of the time -- this table is rarely unregistered item by item and instead the table itself just stops being used. And it's a by value table, not a reference whose lifetime has to be tracked.
So I am strongly contemplating just having one function "Register XYZ.vi", and if the user passes zero for the value to register, that just removes the item from the table (registering zero and not having an entry in the table are functionally equivalent).
"Register" is definitely the verb I want to use -- I gave a lot of thought about that before even asking this question, though perhaps a complete rephrasing of the name.
So my question: Which of these APIs would be, in general, more intuitive to you?
A) A Register and Unregister pair of VIs but where Unregister is almost never used and it is not considered a bug or a leak or otherwise a problem.
B) A single Register VI whose behavior when you register a particular value is to remove the item from the registration.
C) I have a third solution (please post comment below)
-
I created two new nodes in LabVIEW. Really neat, eliminated a problem I was having where the existing G solution was too slow. Then I discovered that one of the nodes inadvertently created a hole in the protections of both VI Server security and library encapsulation. So I patched that. And now it was slower than the original solution.
I feel like Dr. Frankenstein having to shoot his own creation just because it started eating a few villagers. *sigh* Back to the drawing board...
-
2
-
-
Speaking as someone who often sees LV from the underside, I think of this as "Get Data Type Name". The name returned is the name that was part of the data type at the time we compiled this VI for the wire that created the variant. That's the nearest named terminal upstream, but the name is preserved as you pass through tunnels, so it isn't necessarily the name of the nearest terminal.
Having said that, "Get Data Type Name" is a terrible name for the VI for most people because it is not the same as "Get Name of Data Type", which would be "Int32" or "Double". :-) So "Get Terminal Name" is the nearest to technically accurate that doesn't mislead people further. When you start dealing with LV classes, the problem gets even ickier because the name of the data type is always "LabVIEW class instance", the name of the class of the data type is "your class.lvclass", and the data type (terminal) name is "whatever you typed on the nearest upstream non-tunnel terminal".
Summary: I can see why "Get Terminal Name" would be a better name for this VI, and I cannot propose a better one.
-
It takes time to press physical DVDs. We can get the downloads up a lot sooner for those who need the fixes. Pressing the individual DVDs just doesn't make economic sense these days.It would be nice if they published platform DVDs instead of 20 individual installers. We get our developer suite DVDs after a while, but why have to wait.
-
If you're arriving in Austin tomorrow, the Austin Kite Festival is in Zilker Park. 11am to whenever people get tired of flying.
http://www.zilkerkitefestival.com/
I might be there... I just saw this post and have to coordinate plans with people tomorrow before I can say for certain.Location and schedule have been determined!
(Please let me know if there is a way to edit the original post in this thread.)
Sunday, March 4th, 7-10pm (or later if you want to stay, closing is 2am)
Help with event structures
in LabVIEW General
Posted
I realize this is an old thread, but I was pointed toward it as a reason people should avoid Value(Signaling). So, since I am AQ :-), I will pipe up and say: Yes, the order of receiving is guaranteed to be the order of firing. The events use the same queues under the hood as the Queue functions. When you fire from parallel threads, the order isn't known any more than the order of two Enqueues in parallel would be known. But if you fire events serially, it's the same as if you had two Enqueue nodes in order: they go into the event queue in order, and, like all LV queues, they come out in the same order.
There are plenty of parts of Events that I don't know, as it isn't my feature, but I know well the part of events that interacts with the queues. :-)
And, for the record, in this thread you'll find my argument for circumstances when I would use Value(Signaling). I won't say it is wide open, but I believe there are legitimate, even recommended, uses for it.