Jump to content

Aristos Queue

Members
  • Posts

    3,183
  • Joined

  • Last visited

  • Days Won

    202

Posts posted by Aristos Queue

  1. I say this from a standpoint of that I have never heard of anything that ensures that they will be ordered properly.

    There is most likely a high likelihood that they will, but this only highlights that people write programs that assume this.

    If AQ or someone in R&D pipes up and says that it is ensured, then I'll fully retract that. But I will never recommend that anyone write a program that depends on having multiple Val(signl) strung together to execute the events in that order for all those reasons above.

    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.

  2. 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.

  3. 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.

    • Like 1
  4. 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.

  5. Can anyone answer the question: What does "*(type *) &x" mean?
    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."
    NaN - not a number
    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.

    I hate it when mom and dad fight...

    At least he's not drinking tonight. "Two beds and a coffee machine..."
    *

    * Hah! Take that stupid editor. Try to inline my media files when I don't want you to... grrr...

  6. 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.

  7. 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.

    I'm a bit confused on AQ's second "Good usage"... why throw away the error, rather than just handling it downstream?

    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.
  8. 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.

  9. 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?

    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.

    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.

    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.
    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.
  10. 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)

  11. 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...

    • Like 2
  12. 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.

  13. 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.

    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.
  14. 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/

    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)

    The Hideout Pub

    I might be there... I just saw this post and have to coordinate plans with people tomorrow before I can say for certain.
×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.