I have noticed a strange behavior when attempting to communicate with a slow, single shared VISA resource (GPIB device) from multiple stand-alone LabView 5 applications.
Initially, I developed some code which first attempts to acquire exclusive access to the device using VISA lock with a reasonably large timeout. After the lock is acquired, the code performs its IO, then releases the lock. I then wrote some wrapper code which basically tries to enter the (lock, IO, unlock) code as fast as possible. I built a stand-alone application, and ran 3 seperate instances. Basically, I could see that each instance would eventually acquire a lock, perform its IO, and unlock. However, some of the instances "starved" for access to the device, enough so that the timeout was sometime reached (each IO would take perhaps 2 seconds, and I set the lock timeout to say 10 seconds).
Ideally, each instance should receive the lock in the order by which the lock was requested. It appears that VISA is doing something else.
I've verified that this issue also exists with "faster" GPIB devices (say 200ms IO turnaround), but is less noticable because the communications are faster.
To get around this, I wrote another application which basically acts as a resource server. Using VI server, each instance which wants access to the resource sends a "lock" request to the server. Specifically, the "client" calls a re-entrant "Interface" VI via VI Server. The "interface" VI then adds the "lock" request to the queue, and then waits for "Notification" from the server process. The server parses the request queue, and when the resource is available, it sends a notification to the appropriate "interface" VI. This whole time, the client is waiting for the interface VI to return, just like when it's waiting for a normal lock. When the client is done with the device, it sends an "unlock" message to the interface VI. The server then gives the resource to the next item in the queue.
To me, this is a bit kludgey. My solution requires that this "server" application is running at all times, and it is a bit slower than the usual manner. Has anyone come up with a better solution?
How about using a semaphore. That way whomever is using the GPIB (VISA resource) will have the semaphore and release it when done. This will work better than VISA lock and unlock and requires that no VI be a server. Who ever runs first will create the semaphore and the others will just acquire it when they start up. Are you using a GPIB-ENET with multiple computers on a network?
Thanks for your reply. Unfortunately, semaphores are only enforced within the environment in which they are created (ie, within a running development system, or within a single built application). In my case, I have multiple built applications running, so a semaphore created in one has no knowledge of semaphores in other application instances. I am using this approach with my "server" application. When the client connects to the server, it provides the VISA resource string. The server uses this resource string to refer to the semaphore. Since I can refer to the semaphore by name, I don't have to build lookup tables to match LabViews semaphore refnum with the resource string. In addition, I'm not limited to VISA resources; if I have a DAQ shared resource, I could make up some string "DAQ0::channel4" which would automatically be understood.
My answer depends how stand alone your applications are. I don't know what happens if you have several independant executable files but the simplest solution in the development environment is to have one vi that handles all send/receive requests to the instrument. In this way, without extra overhead, you guarantee single parts of each program access too your instrument. (don't make this vi reentrant naturally) This approach has another advantage. You separate in a better way the instrument and your aplication, so changing to another instrument is easier to do.
Thanks for your reply. Within a given environment (be it the development system or a built application), I have seperated out the IO routines into sub-VIs. This absolutely allows easier "drop-in" substitution of different instruments. In fact, I use VI server functionality to allow the users to add and select multiple, "functionally-equivalent" devices, which VI server loads dynamically. However, this solution doesn't work with multiple environments (ie, multiple built applications, at least under 5.0, I'm not sure if 6i is different in this regard). In this case, it is the VISA code which determines access permissions to a device.