levylabpitt / Instrument-Framework

An object-oriented framework for LabVIEW based on JKI SMOs.
BSD 3-Clause "New" or "Revised" License
4 stars 7 forks source link

Reentrancy #99

Closed ciozi137 closed 2 months ago

ciozi137 commented 6 months ago

When needed typically we should use Shared clone (override methods). Exceptions would be, eg, things running in parallel in Lock-In demodulation, and they should use pre-allocated clones. This task is to evaluate existing clones In Instrument Framework and choose an appropriate method. For example, Open and Close in RemoteControl should be shared, but at the moment I think they are pre-allocated

ciozi137 commented 2 months ago

"Shared clones and stateful VIs don't play well together." https://forums.ni.com/t5/LabVIEW/Notifiers-and-Shared-Clone-Re-entrancy/td-p/3856781/page/3

ciozi137 commented 2 months ago

" There are two situations where I have use "Re-entrant Execution". One is the situation you describe -- I want to have multiple (parallel) instances of a processing routine running simultaneously. The other is when I want a recursive routine -- "List all of the Files in this Folder and all of its sub-Folders" -- which you code by making the routine call itself (if you think about the "List all Files" problem, you can solve it by listing all of the files in the folder, then pass each Folder to "List all Files" to list all of the files in the folder, which calls "List all Files" to list all the files in its sub-folders, etc.)

Recursion I usually use Shared Reentrancy, as I don't need VI to be called multiple times. When I've used parallel instances, I've almost always used Pre-allocated Reentrancy.

But what about your question, namely about the VIs that these Reentrant VIs call? The answer is "It depends". If the sub-VI is not reentrant, then all four parallel Instances may try to call the single copy simultaneously. If it does something "fast" (I can't think of a good example right off-hand), then it probably won't make much difference, and will be one less thing to worry about. Perhaps more important, does the sub-VI need to "remember" anything about the VI that called it, such as storing anything in a Shift Register? Then you definitely want a Pre-Allocated clone, so Clone A always calls sub-Clone A, saving A's stuff in sub-Clone A's Shift Register.

I just looked at one of my older "Clone" Projects (I went crazy -- each Clone, up to 24 of them, had three parallel routines, so we could have 96 clones running simultaneously). Most of the sub-VIs at the top level of each Clone were also re-entrant. The exceptions were routines which did simple computations once (like computing the number of buffers I needed, takes little time and is done once/clone) and routines that (quickly) returned a program-updated Global Value (like how many milliseconds had the program been running).

If you want further recommendations, post the relevant code (no pictures, please -- a .zip file representing the compressed folder containing the entire Project is best) so we can better understand your situation.

Bob Schor " https://forums.ni.com/t5/LabVIEW/best-practices-with-quot-shared-clone-reentrant-execution-quot/td-p/4079115

ciozi137 commented 2 months ago

@ciozi137 check SMO and MQT. process.vi in an SMO is shared clone; this might be because it calls itself (call parent method) AND because it is called dynamically (multiple copies): the question is how should methods like open, connect, send, receive, close be: are they reentrant at all?

ciozi137 commented 2 months ago

Shared mainly...

ciozi137 commented 2 months ago

https://www.ni.com/docs/en-US/bundle/labview/page/reentrancy-allowing-simultaneous-calls-to-the-same-subvi.html

ciozi137 commented 2 months ago

https://labviewwiki.org/wiki/Reentrant_VI

ciozi137 commented 2 months ago

RemoteControl v1.1.1 implemented these changes