02-14-2014 07:53 AM - edited 02-14-2014 07:54 AM
Hi all,
Recently I've developed an application that heavily utilizes a single GPIB communication SubVI, which writes a query and reads answers from a single device. In order to avoid collisions, I have deliberately set this VI as non-reentrant.
This SubVI is called by another VI, of course.
Now please consider this situation: what i run multiple instances of the caller asynchronously? Will the non-reentrance policy be respected?
I have hard times debugging the monstrosity I have created and I suspect I deal with collisions here.
Please share your thoughts. Thank you.
EDIT: I'd appreciate if anyone would also share a method of checking whether the GPIB instrument (namely Agilent ENA) is ready for query. I'd implement this mechanism just to be sure the non-reentrance is respected.
Solved! Go to Solution.
02-14-2014 08:08 AM
Opening several references and running an aysnchronous VI will enqueue all the different executions when the callee is non-reentrant. Meaning the callee will run again as soon as it ends its first execution, and will iterate again as long as there's more executions in the "execution queue".
Eric M. - Senior Software Engineer
Certified LabVIEW Architect - Certified LabVIEW Embedded Systems Developer - Certified LabWindows™/CVI Developer
Neosoft Technologies inc.
02-17-2014 12:29 AM
Hi,
I'm not sure if I understand you correctly. Here's what I do: I run three asynchronous copies of the same VI, and the references for each copy are generated separately. I do it in the way shown in AsynchronousCallAndCollect example, in For Loop.
Each of these copies run the same SubVI that is set as non-reentrant.
Is it really non-reentrant?
I started to think that along with each asynchronous copy of a calling VI the callee is copied as well. Hopefully not?
Thank you for your help. Also, if someone knows how to check for GPIB status (if it's busy and should not be bothered), I'll greatly appreciate some help.
02-17-2014 08:29 AM
Dear McTom,
Yes, when you call a non-reentrant VI anywhere in your code, even in asynchronous calls, only one copy will exist, so all other calls to that function will have to wait their turn until the current call finishes executing.
If you need a more sophisticated approach, allow me to suggest migrating your GPIB communication to another loop. You can create a queue to send requests to this loop, and pass the queue reference to all asynchronous calls. This way, you have the ability to closely monitor the loop status (number of elements in the queue, current element, status) as well as some advanced queue handling (priority messages, flush queue).
Kind regards:
02-18-2014 12:22 AM
Andrew,
Thank you for you answer, it surely helped me understand reentrance more deeply.
I like your idea with a command queue - I thought of it as well before. However, it's not going to work since my GPIB module automatically parses commands array and also reads answers when they are expected (Basically, whenever command string contains a question mark). Sometimes it's crucial to hold a block of commands in original order and to be able to catch an array of query answers. That's why I stick to my non-reentrant blocks.
Just to make sure, I have created a local variable containing a reference to a semaphore. This obviously didn't help at all since, as you stated before, this VI is non-reentrant anyway. I think my program's bug lies somewhere else.
Thank you for your time, I think the topic's question has already been answered.