LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

mutiple writers on single-writer network-shared-variable

I hoped to use a 'Single-Writer' Networ-Shared vaiable as a semaphore.  But "Single-Writer" doesn't appear to be enforced all the time.

 

My .vi runs in two applications (one built .exe; the other in LabView development).  The .vi opens the NSV using the PSP "Open and Verify Variable Connection", with access "Read: Allowed; Write: Required".  That always succedes, even if the other application has the variable open for exclusive Write.  I tried reading the attribute 'writeable', but it always returns 'T'.  My .vi then tries to write to the variable.  It usually succedes without error - once.  If the other application started first, subsequent writes usually fail -- but not always!  My .vi then enters a loop where it writes to the single-writer NSV.  When the loop finishes, the NSV is closed.  Both loops have 100ms delays.

 

I've tried different open methods, but they don't appear to be any different.

 

The NI documentation says that accessors are queued up, and when one writer closes, the next one is allowed to write.  It also says that accessor is notified if it can't write.  Are either of those statments accurate?  How can I determine if my application is in the queue or how deep?

 

 

SW NSV.png

(you can probably guess:  1) the hidden 'No Error' sends 'T' to the stop;  2) the hidden 'Error' case does nothing)

 

Note:  The .vi that first opened the NSV never seems to fail.  But the other(s) don't always fail.  I thought writing once was an ugly hack.  I really hate to write several times to test if it really can be written.

 

Note:  The "Single-Writer" never causes a write failure when two .vi's like above both run in LabView development.  It also doesn't cause a failure on two .vi's with front-panel controls bound to the NSV.  However, programatic access always seems to fail if there is a front panel control bound to the NSV (even on the same .vi).

 

My main goal is to get one instance of a program to take over certain low-priority duties (across several apps and several logins).  I meant it to be the first to get the NSV open, but if anyone has an alternate method, I'd like to hear it.

___________________
CLD, CPI; User since rev 8.6.
0 Kudos
Message 1 of 6
(4,008 Views)

When you say you want to communicate between multiple applications and logins, is this with multiple computers or just one?

 

If one computer, consider using named queues.  In this case, you can use a queue across multiple VIs on the same machine.

 

If multiple computers, perhaps you could look into the master/slave architecture in order to accept and give out permissions with greater control.  The master program would be a state machine on the main computer, and slave programs would exist on the other computers.  Permission requests from the slave programs would be stored in a queue and the master program would send notifiers to the slaves when permission is granted.  If I am not mistaken, this should be the functionality you desired when using the single writer network shared variables.  To communicate between the master and slaves, you could use a connectivity process of your choice like TCP/UDP or perhaps a web service or network stream.

 

When using shared variables between parallel loops, one has to be wary of possible race conditions, so I thought the master/slave configuration may be a viable alternative.

 

For more information on master/slave architecture, see this link:

http://www.ni.com/white-paper/3022/en/

 

Here is a separate link that discusses using semaphores with VI Server over a network in case that interests you as well:

http://www.ni.com/example/29413/en/

 

Do you remember where you saw that documentation about accessors?  It is accurate that an accessor is notified if it can’t write, but I’m not as confident about the first statement.  Also, there is not a way to track how deep a request is within a queue.

 

I hope this helps point you in the right direction for your application.

Michael Keane
National Instruments
0 Kudos
Message 2 of 6
(3,960 Views)

Thank you.

 

For now, I only want to do this on a single computer, but would like an option to extend it to multiple computers later.  I have a method to spread to other computers, if the shared variable method doesn't work.  Basically, one application declares itself 'master', and others submit to it.

 

I'll try the named queues as soon as I get a chance [I'm out of time today].  But other things I've done show that a named queue is part of a single application, and two applications that request a named queue (by the same name) actually get two different queues.  I have at least a dozen applications running using a named queue with the same name, and never noticed any cross-talk (but I never was looking for it).  (This is on Windows 7-64, using 32-bit LV).

 

I'll definitely check out the VI server for semaphores example.  I've been doing master/slave TCP programs since about 1991, so might not check out that one.

 

I don't have the link now for the documentation I referred to.  I found it by looking for "single-writer", and sifting through for descriptions.  The same text showed up on several pages (I think 2 were white-papers).

 

[I want to appologize for slow responses.  I have several jobs to work on, most of them are away for the office.  This job is important, but not that urgent.]

___________________
CLD, CPI; User since rev 8.6.
0 Kudos
Message 3 of 6
(3,920 Views)

Unless I've missed something important, Semaphores and Queues don't work across instances of an application.  The documentation for Obtain Queue specifically says it doesn't work, and I've tested Semaphores to be sure.  I tried using the "\\.\Name" format for the semaphore name, in case it is able to use the Windows multi-process semaphores.  But each instance of the application gets a different semaphore.

 

I can't find a good solution, so I'm going to write my own.  In short, I will have two shared variables (with Single Writer and Buffering[10]).  One will be for any application hoping to take the semaphore; the other for one application to hold onto it.  Both will hold the task ID# of the requester/owner.  The owner will have to keep writing to the OwnedBy, so if it crashes or is closed without releasing it, others can claim it.  If OwnedBy is 0 or stale, anyone wanting the semaphore can write to Request.  The first one to get a taskID into Request has the right to write its taskID to OwnedBy.  The biggest down-side to this implementation is that each time an owner releases the semaphore, there is a big brawl for next, instead of using a queue.  I considered using the buffering feature of the Request variable, but it would create a lot more overhead to make sure the requesting .vi still wants the semaphore.  Applications must be able to start at any time.  I beleive as long as each application reads both shared variable queues completely before making a request, that it should still work.

___________________
CLD, CPI; User since rev 8.6.
0 Kudos
Message 4 of 6
(3,811 Views)

The documentation is unclear about this.  One description says "Sets the shared variable to accept changes in value from only one target at a time".  It then says that the engine "restricts writing to a single VI on a single computer", but then explains that the first instance of LabVIEW that connected to the Shared Variable can write values, and any subsequent instances cannot.  [You do know that this applies only to Network-published Shared Variables, don't you?].  However, that latter restriction says nothing about two VIs on a single target writing to a "Single Writer".  This might be something that NI missed ...

 

BS

0 Kudos
Message 5 of 6
(3,794 Views)

I was worried that my previous post only spouted what NI wrote, but that I hadn't tested things myself.  Now I'm more confused than ever!

 

I wrote a routine that used two sub-VIs to write to a Network Shared Single-Writer Variable, to test the "one-writer" notion that limited it to one VI.  I had Test 1 write the number 1 to the NSV, and Test 2 write the number 2.  After each write, I did a Read NSV.

 

When I ran it the first time, I got two 0's, and an error code of -1950679034, The Shared Variable has no Value. I ran again, got two 2's.  Then I remembered that the Network Shared Variable has an "engine", and it takes time to move the new value to the Engine.  I tried several things to figure out the timing, and couldn't manage to do so.  But I pretty much convinced myself that each of my Test VIs was, in fact, setting the Variable (so much for Single Writer -- it is not limited to a "single VI").

 

It has been several years since I last played with Shared Variables.  When they first came out, I tried to make them work.  Then NI introduced Network Streams, and I've never looked back.  I do use Local Shared Variables, treating them sort of like "Global Variables with an Error Line", but every time I've tried to use NSV, I've been burned.

 

Good luck.  If you figure out how to get things to work as NI says they should, post it here!

 

Bob Schor

0 Kudos
Message 6 of 6
(3,785 Views)