Jump to content

mike5

Members
  • Posts

    160
  • Joined

  • Last visited

  • Days Won

    3

Posts posted by mike5

  1. Well, I'm glad I have some options (setting VI/process priority was on my list as well, but I was looking for all possible options), but to answer some other questions as well.

    Regarding "arbitrary execution time" - as we all know, things change in a live system. Sometimes the application has to log some things, and sometimes it doesn't, so unless you are really doing just one specific thing on a real-time system, you don't really know how long an iteration may last.

    As I already stated, I am aware of the VI priority, but that only offers me 5 priorities with one that I think it's best avoided (the RT one). Timed loop offers 65535 priorities, but maybe 4 will be enough after all.

    I'll look into the thread that ShaunR suggested and hopefully find what I need there.

    Thank you all for your help, and if you have any other ideas, please keep them coming :)

    Mike

  2. Hi all. We have a project where parallel loops are needed, but also setting priority for each loop is a requirement. At first it seemed that "Timed loops" are an answer to these problems, since they support priority, but "Timed loops" have other problems with the code that doesn't execute quickly enough.

    So, in short I am looking for a solution that would give me the ability to set priorities for parallel loops and also support arbitrary execution time for each iteration.

    Thanks in advance, Mike

  3. Sorry for the late reply, I was not able to check this for a while...

    The two changes are:

    - VI recompiled: Changes to front panel data structure or block diagram data flow causes LabVIEW to recompile the VI, generating new execution code.

    - SubVI call(s) modified: A subVI's connector pane (or a polymorphic subVI's list of VIs) was modified. Show the Context Help window for the subVI and make sure the connections to the subVI on the block diagram are still correct.

    And I have not touched the code... And no xControl used.

    Br, Mike5

  4. I have an application composed of many objects, but whenever I shut it down and close the project it prompts me to save one of the VIs (always the same one), as if it was modified. I have inspected that VI and I cannot see what is causing this. Does any anyone know what may be going on?

    Thanks in advance, Mike

  5. I have this rather strange problem. The VI I'm working with is based on a rather complex home-grown LVOOP. If I open the project and run the VI, then it works as it should. Then I stop it (from within the application, not "Abort Execution") and start it again, and it does not work as expected - it runs, but doesn't do what it is supposed to do.

    Then I add a strategically placed breakpoint, start it, and the VI works every time (I just need to hit "Continue" when it reaches the breakpoint). With the breakpoint active I can stop and start it as many times as I want. When I remove the breakpoint, the VI again starts working only on the first run again.

    Does anyone have a clue what is going on here?

    Miha

  6. It's been that way for 25+ years. I doubt that anything substantially altering that situation is likely anytime soon. I actually find the experience fairly straightforward when I compare it to 4000 lines in a .cpp file that I'm scrolling up and down through. Even in C# where files tend to be on the order of 100 lines, the windowing situation gets pretty bad. At least with LV you can observe from the probes behavior at deep levels of the program instead of having to actually be watching those levels real time to see watch window results.

    I'm pretty new to this, but I think having a way of saying "Don't open front panels for SubVIs during tracing" would help a lot...

    That, by the way, is the number one reason to not use data value references. Yes, they're bright and shiny and new in LV 2009 and a bijillion users have thanked us for adding them to the language, but I continue to argue that the vast majority of the time the same work can be achieved with dataflow and doing so would avoid the deadlocks and race conditions that too often crop up. Yes, there are rare situations where you really do need a DVR, but its way less common than most people seem to believe. Perhaps having spent two days searching for the deadlock, you'll now spend a couple days thinking about whether it is possible to architect your code without any DVRs to avoid this in the future. I'm not saying it is necessarily possible in your case, but I believe it is worth thinking about.

    Well, we have a collection of "active objects" communicating with each other, and they all have some parallel loops as well. IIUC each "process" and parallel loop gets its own copy of the attributes, which doesn't help much. Or am I wrong?

    Miha

  7. I suggest you upload your code if you can't solve this.

    In general, only DVRs do the lock and in fact, that's their defining behavior - they allow you to share a single block of data by locking it when it is accessed. If your code gets stuck, I would guess that you ran into a deadlock - both places are stuck waiting on each other. As mentioned, under normal circumstances this doesn't happen. If the DVR is the only lock you have in the code, make sure the reference wire does not cross the border of the IPE structure into it.

    Yes, I have identified a deadlock as well. Unfortunately it was wrapped into multiple layers of VIs, so it wasn't obvious at first and required two days of tracing to discover.

    And on that note, am I the only one who finds debugging/tracing in LabView more useless than useful - with each VI opening two windows until you're completely lost. Any plans on somehow making the experience better?

    Thanks for all your help. Miha

  8. This I believe is true, but an IPE (in-place structure) will only fail to obtain the lock if it's supplied with an invalid reference: the DVR has been deleted, a Not A Refnum (or similar) was supplied, etc.

    An IPE will only block (wait, or "freeze") if another IPE is currently working on the reference (this is not an error). The IPE will signal (resume execution) when the reference becomes available again. A semaphore is traditionally how you protect resources like this, but there's a semaphore inherently built into the DVR as only one IPE can access it at a time. Under most situations you shouldn't need to protect the DVR with an explicit semaphore.

    Thanks for your answer!

    Is the implicit semaphore implemented for all types IPE structures, or just the DVR related ones? If it is DVR only, don't other instances need it?

    Also, do you happen to know how is the semaphore locking resources-wise? Greedy? Slow? Alright? I'm hesitant to remove it now that I have it working, but I might sometime in the future, if all it does is to re-implement something that's already there.

    Br, Miha

  9. Hi all,

    IIUC (from some other threads on this forum) if in-place element fails to obtain a lock, it gives an error and provides you with a default value of whatever the reference points to, and continues.

    But that's not what I'm seeing.

    If an in-place element on DVR is used from two processes, then one of the processes simply "freezes" (enters an endless wait maybe). Also, since my DVR always point to a cluster, I'm using in-place element inside an in-place element (outer one for DVR, inner one for bundle). I'm mentioning this just in case that the freeze-up doesn't occur from accessing the DVR, but the bundle...

    Can anyone shed some light on how to process the same bundle from two different processes? Currently I have resorted to using semaphores to avoid the problem (and it seems to work), but is this the right way (performance-wise), or is there a better way?

    Thanks, Miha

  10. Can't answer the RT part of the question.

    For your second question though, you could store the size of the table in the variant itself as it is not used for anything else in this scenario. Just remember to update the count whenever you add or remove a key/value pair.

    -Scott

    What an excellent suggestion :) Thanks.

    Miha

  11. For all LabVIEW built in LabVIEW refnums you can simply use the Not A Refnum primitive in the Comparison palette. This will not just check if the refnum is a NULL refnum but actually verify that the refnum refers to an actually still opened object. I'm not sure if your shared variable refnum is a built in refnum or some pseudo refnum but you can easily try that out.

    This function has the additional advantage that it does not depend on some strange features in newer LabVIEW versions. If you compare certain refnums (VI server refnums) with the (Not)Equal function since LabVIEW 8.0 you do get for instance equality eventhough the refnum is technically not the same, but it does point to the same object (VI refnums work for instance like that).

    Yes, I was aware of this function, but I am not looking for a way of comparing two refnums (I'll need it of course), but I am looking for a way of instructing "set this variable to not-a-refnum".

    Miha

  12. I don't know whether to ask this here or on the other thread, but are there any drawbacks about using Variant Attributes on real-time targets? Besides memory... And on that note, is there a better way of getting the number of the elements in the Variant than producing names/values arrays just to get the length?

    Miha

  13. Is there a way to create a not-a-refnum of a specific type (sort of like NULL pointer)? For example, the shared variable refnum. Is it even necessary? What I would like to do is have a list of shared variables that I have opened, and I would like to know if the refnum is valid or not without some extended logic that tries to read from it or something like that...

    Miha

  14. Hi all,

    the document at http://zone.ni.com/devzone/cda/tut/p/id/4679 in the section titled Programmatic Access says:

    "As discussed above, you can create, configure, and deploy shared variables interactively using the LabVIEW Project, and you can read from and write to shared variables using the shared variable node on the block diagram or through front panel data binding. New in 2009, LabVIEW also provides programmatic access to all of this functionality.

    Use VI Server to create project libraries and shared variables programmatically in applications where you need to create large numbers of shared variables."

    I'm mostly interested in the last part, that is, creating Libraries and shared variables from the VI programmaticly, but I was unable to find the right components to achieve that (I'll keep trying, though). Can someone guide through the process or point me to a VI that does that?

    Thanks in advance, Miha

  15. Mike5,

    This link will describe many of the design patterns...

    http://decibel.ni.co...t/docs/DOC-2875

    In particular it has a zip file with an implementation of the factory method. While it does not create a static VI reference since a class is really not a VI, it uses the path of the class and converts it using the Get LV Class Default Value VI. This implementation is interesting because it does not load the desired class into memory until the Load By Enum VI is called (this VI is part of the project).

    There are alternate ways to get the Factory to understand what classes it can create rather than an enumeration. Perhaps it could have a registration method where some other VI tells it to add a class path to its list - creating something like a name-value pair (probably implmented as two arrays - one with name, the other with path). The name would be something your application would use to tell the Factory to create. The value would be the path to the class. Alternately, if memory does not concern you, you can give the Factory an instance (rather than a path) of the classes it creates. The Factory would simply return the entry in its list based on the name it used to look up. Remember that as a data flow language, the class the factory got out of its list is an independent copy (unless you start using data value references in the class's private data). More on the DVR when you get to that point - there was an earlier thread on that subject.

    I hope this helps.

    Kurt

    Thanks, I was looking at the Factory_UsingVIs.zip , which is referenced from a PDF with the same contents as your link. This one somehow creates that Strictly typed VI Ref which the Context Help then shows that is is really a reference to a lvclass. And that I could not recreate. I'll look at your example as well, thanks.

    And, yeah, I do use DVR in the class private data.

    Miha

×
×
  • Create New...

Important Information

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