LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

dl multiple calls

Briefly this is the problem (LABVIEW 2013sp1):

I placed on the diagram TWO instances of the SAME subvi connected in SERIES by the error wire.

The subvi contains a CLFN calling a function of a dll. The dll keeps STATIC variables inside. Each time called, the dll shoud return a different value for one of the pointers (int32) passed to the of the function.

Problem: the two subvis return the SAME value for the above mentioned pointers!

If I place a wait (500ms) between the two subvis, the two pointers result DIFFERENT, so the behaviour is OK.

 

What the hell?

 

thanks

Fabrizio   

0 Kudos
Message 1 of 5
(2,160 Views)

Without providing any code it sounds to me like you have a Race Condition.

 

In short, a Race Condition is a Computer Science term used to describe when two threads (concurrent computer programming segments) access the same element "at the same time".  When I say "at the same time" i mean they "try" to access the same element at the same time.  As a result, you have a "race' where the output is different depending on who gets to access the data first.

 

A simple example:

 

You have $5 in the bank that you and your wife share.  Your wife calls you and tells you to put more money in the account so she can buy shoes.  Unfortunately, your wife is impatient.

 

At "roughly" the same time: 

 

1. You try to deposit $10 before your wife gets out money for the shoes.

2.  Your wife tries to buy the shoes with a check (that is electronically/instantly cashed).

 

You have a few outcomes:

 

1. You deposit the money just before she buys her shoes.  This is the desired outcome.

 

2. Your wife tries to buy the shoes with the check just before you deposit the money.  Your check bounces and now you have an unhappy wife, an unhappy bank, and an unhappy store.

 

This is probably what is happening in your program.  For instance (in C)

 

int x = 0;

 

Program A:

 

x = x + 5;

 

Program B:

 

x = x + 5;

 

If you tell it to run program A and then B on two different threads, you have a couple of outcomes:

 

1. Program A goes first and adds 5 to x.  (x = 5 now).  Then Program B goes and adds 5 to x.  (x = 10 now)

 

2. Program B goes first and adds 5 to x (x = 5 now).  Then Program A goes and adds 5 to x (x = 10 now).

 

3. Program A and B go at the same time (approximately -- the computer functionality is being abstracted here) and both see that X = 0.  So they take 0 and add 5 to get (x = 5).  Both programs store "5" in "x".  (x = 5 now).

 

This causes problems since you cannot guarantee your output.  This is likely what is happening to you.

 

Why is this happening and how to fix it?

 

Well, there are really two ways.  First, you could edit the .dll (if you wrote it) and add Mutual Exclusion via Semaphores.  (Complex computer elements that ensure shared resources between threads don't cause Race Conditions).  This is likely not your answer unless you wrote the library.

 

The second option is a LabVIEW issue that you can control.  By linking the dataflow to these two calls in parallel, LabVIEW will automatically run them on seperate threads (to try to do twice the work at once to decrease overall execution time).  To prevent this, ensure that one runs before the other by wiring the errors in serial.  (One before the other).

 

**Note:  It is also possible this isn't your issue, but you described a common Race Condition issue so I am assuming the above should apply to you.  If not, it is good to know nonetheless 😄

 

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Edit:

 

Upon second reading it could also be a memory allocation/garbage collection issue.  If you did not allocate or deallocate memory in the "dll" appropriately, it is possible that your pointers are overlapping one another and reading garbage off the stack in one instance.

 

Without your code or a more actual description of the problem (using technical terminology), I can do nothing more than suggest "possible" problems.

 

Edit2:

 

I also presume the "dll" was created using a C language.  They have multiple uses of the word "static".  Read here for more info on which type you are using.  (This is another instance in which attaching actual code would help clarify your problem.)

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
If someone helped you out, please select their post as the solution and/or give them Kudos!
0 Kudos
Message 2 of 5
(2,139 Views)

It should not be a race condition, because the two instances of the subvi (named A.vi) are connected by the error wire, therefore the execution flow  is known. The first subvi (A.vi) is executed, then the error cluster is passed to the next subvi (A.vi).

Both vis give in output an int32 called "p". If I put in the diagram a 500ms wait between the two calls the program is ok. Withoout the wait function, both the vis  (A.vi) give me always the same value for p.

The variable p computed by the dll is not declared as static in the c code. Anyway, the attribute "static" is not relevant, because the behavior is dependent on the time passed between the consecutive dll calls. If the bug is due to the c code, the strange behavior should occur always, even if I put the wait function between the two consecutive calls of the d.. 

0 Kudos
Message 3 of 5
(2,125 Views)

I have never encountered a timing issue with single threaded DLLs in LabVIEW.  Unfortunately I do not have any other suggestions.  If you are able to upload the code, a mistake may be more easily visible.  But I also have LabVIEW 2009 so perhaps there is a bug in the newest version.  I am unfamiliar with it.

 

**Also I must have misread the part about the errors already being in series.  That does seem to rule out Race Condition as they shouldn't be on different threads.

 

(One thing to double check is that it is set to run in the UI thread.  This would prevent any Race Conditions as well)

 

3. Declaring a function call to a library function threadsafe (reentrant)

If you know that the function you are calling in the library is threadsafe, you may inform LabVIEW by appropriately configuring the node. If the node is not configured as a threadsafe call, the call is assumed to be non-threadsafe, and is run in the User Interface thread. This ensures that two calls are not made simultaneously to a non-threadsafe function. If the function is threadsafe, however, it should be configured as such, as this leads to performance improvements.

To configure a call library function as threadsafe, change the dropdown box that says "Run in UI Thread," to "Reentrant."


Having done this, the top of the node changes from orange to yellow, indicating that the call is reentrant.

---->

 

 

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
If someone helped you out, please select their post as the solution and/or give them Kudos!
0 Kudos
Message 4 of 5
(2,120 Views)

I cannot upload the code because it belongs to a huge project and library. I should write new code to replicate a similar condition and upload the vi/dll here. Naturally I tried to set the vi as reentrant and to move the dll thread in UI or in any... all th possibilities.

no way

0 Kudos
Message 5 of 5
(2,110 Views)