Yamaeda Posted May 28, 2010 Report Share Posted May 28, 2010 Hiya! I've got a vi which has 2 loops. Loop1: vi's with dll based IO through a dedicated PCI card. Loop2: ActiveX-based com through RS232. ActiveX is quite slow, about 200ms/call, but that's not the issue (although annoying). I check status by polling through 5 activeX calls, thus 1 sec. The Loop1 easily loops at 3ms if needed, i run it at 30. Lots of time to spare. That is, until i start the 2nd loop. Suddenly Loop 1 runs at 1 sec also and the only explanation i can think of is that ActiveX locks my VI/labview somehow. If i add some small waits between the activex calls loop1 runs a few loops at full speed, then a 200ms loop (the activex time). Anyone has any idea of how to get around it? (labview 8.2) /Y Quote Link to comment
Ton Plomp Posted May 28, 2010 Report Share Posted May 28, 2010 Make sure that the DLL is run as thread safe (or not), I never dealt with such an issue but it sounds like both processes run in the UI thread. Ton Quote Link to comment
Yamaeda Posted May 28, 2010 Author Report Share Posted May 28, 2010 I've also wrapped the activeX in a VI of it's own and set it to another thread, same with the dll-vi's. The main difference is that i dont get timeouts any longer (as it seems to have broken into the dll sub-vi's). Yes, somehow they must work in the same thread (probably UI), but it feels very strange, to say the least. /Y Quote Link to comment
Rolf Kalbermatter Posted May 28, 2010 Report Share Posted May 28, 2010 I've also wrapped the activeX in a VI of it's own and set it to another thread, same with the dll-vi's. The main difference is that i dont get timeouts any longer (as it seems to have broken into the dll sub-vi's). Yes, somehow they must work in the same thread (probably UI), but it feels very strange, to say the least. The Call Library Node has its own threading configuration that allows you to select that the DLL function is either called thread safe from the UI thread or in reentrant mode in whatever thread the calling VI is executing. If you have the UI Thread selected in the Call Library Node you can put the VI in whatever execution system you want but in order to call the function LabVIEW will switch to the UI thread first. I believe that most ActiveX nodes have to be called thread safe at all times, so they will execute in the UI thread anyhow (since most ActiveX components are specified to be apartement threaded, which is to say that an application should always call the Active X component from the same thread and the UI thread is the only thread in LabVIEW where this can be guaranteed without a very complex thread configuration system that nobody would understand. 1 Quote Link to comment
Yamaeda Posted May 28, 2010 Author Report Share Posted May 28, 2010 Hmm, interesting idea, i'll have to look into the Call Library configuration of the drivers. However, shouldn't the multitasking force the 2nd loop to run more often? Any other idea of a possible fix/workaround? /Y Quote Link to comment
Popular Post Rolf Kalbermatter Posted May 30, 2010 Popular Post Report Share Posted May 30, 2010 Hmm, interesting idea, i'll have to look into the Call Library configuration of the drivers. However, shouldn't the multitasking force the 2nd loop to run more often? If the DLL call and ActiveX call are both UI threaded (ActiveX as said is most likely, DLL depends on the Call Library node configuration but if it is a driver you haven't written yourself I would be vary to change a possible UI thread setting to re-entrant as that could cause all kinds of weird problems in the DLL if its functions aren't explicitly written to be re-entrant) you get most likely following scenario: Since the ActiveX call takes a certain amount of time, LabVIEW can't interrupt it midway to switch to the DLL call and let it take over the same UI thread. Once LabVIEW hands over control to an external code (ActiveX or DLL) it can only wait for that code to return code back to LabVIEW before doing anything else in that same thread. There is not a single way around it. I can give you a solution that will work. Create two LabVIEW executables, one calling into the ActiveX component and the other into the DLL, and let them communicate through Inter-application Communication together. That solves the problem since both components now reside in separate processes and will be simply multitasked by Windows itself. Changing the Call Library Nodes to run re-entrant might be a solution, but without knowing the underlying DLL code I would never make such a change myself. If it is not set re-entrant this has most likely a reason. It could be just an omission from the actual programmer but the chance that the DLL uses global variables and resources between functions without protecting them explicitly is very high and in that case changing the VIs to allow re-entrant calls could in the best case lead to crashes in the worst case to strange and almost impossible to debug effects. One other option is to change the Call Library Node to be re-entrant and assign all Driver VIs to a specific execution system. Now you go into vi.lib/utility/sysinfo.llb/thread config.vi and run it. In that VI set the execution system you have chosen to assign to all driver VIs to only have one thread. This will likely work fine but has the disadvantage that the thread configuration is not part of the VI but of the LabVIEW runtime setup. So you will have to make sure to add the according lines in labview.ini, that this change will create, into any executable ini file as well as any other LabVIEW development system ini file that you may use, such as other LabVIEW development versions you may use or other LabVIEW installations on any other machine that wants to make use of that library. 3 Quote Link to comment
Yamaeda Posted May 31, 2010 Author Report Share Posted May 31, 2010 I must say neither of your solution really tickle my "oh i must program that"-nerve. I was hoping for just setting the dll call to "any thread" and keep the VI as non-reentrant to protect it but allow it in another thread than the UI one. I checked today, and they are all set to UI thread currently. The drivers are quite old, probably from LV5 or something originally so the multithreading probably wasn't in the design. A coworker actually did the 2 application test today and it worked well. I dont think any of us has done inter-application solutions before though, so that solution has some hurdles but might be a good solution. I'll have to dig deeper into the different solutions. /Y Quote Link to comment
Yamaeda Posted August 25, 2010 Author Report Share Posted August 25, 2010 Now i've had time to return and try some more on this issue. Changing the DLL calls to Reentrant and then changing the VI execution thread made alot of difference! I haven't actually tried it coupled with the mentioned ActiveX, but i got similar problems in another program that uses several parallell processess instead. In this one the Open VI-node caused the DLL calls to generate errror 7005 (timeout). The mentioned changes (some 6 dll calls and vi's preferred thread of execution) has solved it beatufully! Thanks alot Rolf! (cant mark as solved or something on this forum, can you?) /Y Quote Link to comment
crelf Posted August 25, 2010 Report Share Posted August 25, 2010 (cant mark as solved or something on this forum, can you?) Nope, but you can vote a post up by clicking the green (+) ball on the lower right of the post. LAVA is more of a forum than a collection of Q&A threads, so we didn't think it made sense to allow members to mark posts as specific categories (like "Solved"). Quote Link to comment
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.