4.1.2 - Multi-Threaded Operation [U3 Datasheet] | LabJack
« Close

Datasheets and User Guides

App Notes

Software & Driver


4.1.2 - Multi-Threaded Operation [U3 Datasheet]

The UD driver is completely thread safe. With some very minor exceptions, all these functions can be called from multiple threads at the same time and the driver will keep everything straight. Because of this Add, Go, and Get must be called from the same thread for a particular set of requests/results. Internally the list of requests and results are split by thread. This allows multiple threads to be used to make requests without accidentally getting data from one thread into another. If requests are added, and then results return LJE_NO_DATA_AVAILABLE or a similar error, chances are the requests and results are in different threads.

The driver tracks which thread a request is made in by the thread ID. If a thread is killed and then a new one is created, it is possible for the new thread to have the same ID. Its not really a problem if Add is called first, but if Get is called on a new thread results could be returned from the thread that already ended.

As mentioned, the list of requests and results is kept on a thread-by-thread basis. Since the driver cannot tell when a thread has ended, the results are kept in memory for that thread regardless. This is not a problem in general as the driver will clean it all up when unloaded. When it can be a problem is in situations where threads are created and destroyed continuously. This will result in the slow consumption of memory as requests on old threads are left behind. Since each request only uses 44 bytes, and as mentioned the ID’s will eventually get recycled, it will not be a huge memory loss. In general, even without this issue, it is strongly recommended to not create and destroy a lot of threads. It is terribly slow and inefficient. Use thread pools and other techniques to keep new thread creation to a minimum. That is what is done internally.

The one big exception to the thread safety of this driver is in the use of the Windows TerminateThread() function. As is warned in the MSDN documentation, using TerminateThread() will kill the thread without releasing any resources, and more importantly, releasing any synchronization objects. If TerminateThread() is used on a thread that is currently in the middle of a call to this driver, more than likely a synchronization object will be left open on the particular device and access to the device will be impossible until the application is restarted. On some devices, it can be worse. On devices that have interprocess synchronization, such as the U12, calling TerminateThread() may kill all access to the device through this driver no matter which process is using it and even if the application is restarted. Avoid using TerminateThread()! All device calls have a timeout, which defaults to 1 second, but can be changed. Make sure to wait at least as long as the timeout for the driver to finish.


I am a new user of the U3 and have a simple application running that samples an analogue input an logs the data to a graph when required. It all works well!

However, my sampling is running in a thread which I have set up to also toggle two digital outputs based on another digital input.

I can see through the software that the inputs and analogues are updated... I can see the request to the U3 is also toggling the outputs... what I can't see is a response at the physical outputs.

If I run the some routine external to the thread everything works perfectly... I guess I'm missing some key trick here but I'm darned if I can spot the problem.  

If the DO commands execute and return without error, then I suspect they are working.  Perhaps the other thread is doing something that immediately sets them back?  I suggest you contact us by email or our forum and share some code that demonstrates the issue.