LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

LabVIEW CLFN and multithreading in dll QT

I created dll wrapper for QT-dll library. In QT-dll there are two thread, each of which creates one text file and writes in it the current time. I run the dll-wrapper using LabVEW CLFN. As a result, a file is created only in the first thread. The second thread doesn't work. There are what ideas?

The archive contains the project and QT libraries required to run the project.

WriteFile

0 Kudos
Message 1 of 4
(3,524 Views)

I have been looking for information on that topic of threads and dll calls from LabVIEW for a while and could not find much information.

 

However, I suspect that you cannot open a 2nd thread in a dll called from LabVIEW based on the following info I found in LabVIEW 2016 Help:

 

  • ... If you want to write a shared library that performs a long task, be aware that LabVIEW cannot perform other tasks in the same thread while the shared library executes.

If you can find more information, post it, I'm interested.

Marc Dubois
0 Kudos
Message 2 of 4
(3,474 Views)

Well that is not something LabVIEW specific. A thread can only be executing one piece of code at any time, in LabVIEW or in a C program. When you create a VI and in there place a Call Library Node to call a DLL function, what will happen is that LabVIEW calls the function from one of its threads and that thread is then consumed by the DLL function until it returns.

 

Now if you have not configured the Call Library Node to be reentrancy safe, LabVIEW will execute it in the UI thread. That thread executes everything that LabVIEW doesn't know to be safe to execute reentrant. So if you have two different VIs with each a Call Library Node and both of them are set to be executed non-reentrant, then one has to wait until the other (and many more things like the UI drawing in LabVIEW) is finished before it is executed.

 

Now lets suppose you have one VI with a Call Library Node that is set to be reentrant and you call that from two different places. VIs are by default not set to execute reentrant. So the second call has to still wait until the first VI is finished. Only when you set the VI to be reentrant (VI Properties->Execution->Reentrancy) to either shared clones or preallocated clones, can LabVIEW execute both in parallel. The big question then is however if the DLL function itself can deal to be called reentrant. That is something only the DLL programmer can really know and answer.

 

There isn't anything inherently strange about how LabVIEW deals with threads. They are basic OS resources and every application has to observe the constraints that the OS imposes on the use of them. LabVIEW does a very decent job in that respect. What is special in LabVIEW is that you can write code that makes inherently use of multithreading without normally having to worry about the details yourself. But that idea breaks down as soon as you use external DLLs. The standard C interface used by DLLs has no means whatsover to facilitate the communication from the callee to the caller about its multithreading capabilities or lack thereof. So you as programmer of the VIs interfacing to the DLL through the Call Library Node have to tell LabVIEW if it is safe to call a particular function reentrant. For safety reasons LabVIEW starts with a non-reentrant default value because calling reentrant code single-threadedly is no problem, but the opposite can cause all kinds of very nasty problems, where a plain crash is one of the more convinient problems you can encounter.

Rolf Kalbermatter
My Blog
0 Kudos
Message 3 of 4
(3,448 Views)

And after downloading the code and looking at it it is a matter of 1 minute to point out your error!!

 

in write_lv->write() you create a Write_File object assigning it to a DLL global variable write_file!!

 

Since you use a global variable, this function is not reentrant safe and so the only way to make sure it executes properly is by telling LabVIEW to execute this function in the UI Thread, but then it won't execute in parallel.

The fix however is pretty simple: make write_file a stack local variable instead by declaring it as (non-static) variable inside the function. Then you can configure the LabVIEW Call Library Node to execute in any thread and you will get both parallel execution as well as multi-thread safe code (as far as the write_lv.cpp file is concerned, I don't feel like checking your entire code for reentrancy bugs).

Rolf Kalbermatter
My Blog
0 Kudos
Message 4 of 4
(3,441 Views)