LabWindows/CVI

cancel
Showing results for 
Search instead for 
Did you mean: 

How to Setup Functions that will be used in Multiple Threads?

Hello,
I have walked into a project of pre-existing code that I must enhance, repair, etc.
This project uses 3 threads, and each thread "owns" a particular piece of hardware, for example:
Thread 1: owns DC power supply
Thread 2: owns waveform generator
Thread 3: owns NI multifunction I/O DAQ card

I am using the term "own" to indicate that all functions that perform actions on that hardware are performed within that thread (for example, the source code of Thread 1 has functions like InitPowerSupply, ProgramPowerSupply, PowerSupplyOff, etc.).

I'm not sure I like the architecture, but it's what I've walked into and so I am trying to live with it.

One question I have is: how to access functions that reside in one thread while running in a different thread? For example, say I'm in Thread 2 and I want to turn off the power supply by calling PowerSupplyOff(); What is the best way to do this? I could declare the PowerSupplyOff() function as an extern in Thread 2 and just call it directly--in this case, does the compiler make a separate copy of this function, one copy for each thread that calls it, or is it one piece of code that is shared between threads (if the latter is true, what are my synchronization options to avoid competition between calling threads?)? Another option would be to use SetEvent to signal Thread 1 that Thread 2 wants to call PowerSupplyOff--then, in Thread 1 source code, there could be an event case to simply call PowerSupplyOff()--this option localizes all hardware calls within the thread that owns that particular piece of hardware--but is that necessary?
Long question, but to summarize: in Thread 2 is it OK to simply declare the power supply functions of Thread 1 as externs and call them directly?
If anybody has any thread architecture philosophies, too, I would be very interested in hearing your opinions.

Thank you!
-SciAuto
0 Kudos
Message 1 of 3
(3,110 Views)
In an environment like the one you have described I whould use PostDeferredCallToThread to interchange messages between threads.

You could look at this discussion that covers a different item (UIR updating in multi-threaded applications) but with some parallelism to your actual problem.


Proud to use LW/CVI from 3.1 on.

My contributions to the Developer Community
________________________________________
If I have helped you, why not giving me a kudos?
0 Kudos
Message 2 of 3
(3,094 Views)
Sci,

With the setup you described, if you want to have an on/off for the power supply called in two different threads you can make sure that they are exclusively called from one another. Check out the functions CmtNewLock, CmtGetLock, and CmtReleaseLock. However in my opinion it would probably be better to have both of the functions in one thread. Let me give you an example why.

Thread 1 which contains all of your hardware functions (with the exception of PowerOff), has to do some calculations that take up say 5 seconds before it can actually get to the PowerOn function (I know this may be unrelastic but go with me for arguments sake :-).

Thread 2, which contains the PowerOff function doesn't have any overhead and it will get to the PowerOff function in <1 second.

Now, the user has a button in the GUI for power on and power off. The user presses the power on button and then quickly realizes that they don't actually want the system on yet. So within 2 seconds they hit the power off button. At this point, the PowerOn function hasn't run yet (so your lock shouldn't be taken), and the system is already shut down. So what will happen is that the PowerOff function will do nothing and then just complete. Next thread 1 will finally get to PowerOn and turn the machine on. But the machine won't turn off because the PowerOff function has already been run. Thus the user has told the machine to turn off but it didnt.

An issue like this could be resolved by throwing locks around entire threads, but generally you want to keep your mutual exclusions to the most minimal amount of code as possible. Wrapping threads in mutex's is bad practice.

Thats my 2 cents.
0 Kudos
Message 3 of 3
(3,093 Views)