National Instruments NI-488.2 User Manual

Page 85

Advertising
background image

Chapter 8

NI-488.2 Programming Techniques

NI-488.2 User Manual

8-10

ni.com

Assume that a process has two separate threads that make NI-488.2 calls,
thread 1 and thread 2. Just as thread 1 is about to examine one of the
NI-488.2 globals, it gets preempted and thread 2 is allowed to run. Thread 2
proceeds to make several NI-488.2 calls that automatically update the
NI-488.2 globals. Later, when thread 1 is allowed to run, the NI-488.2
global that it is ready to examine is no longer in a known state and its value
is no longer reliable.

The previous example illustrates a well-known multithreading problem.
It is unsafe to access process-global functions from multiple threads of
execution. You can avoid this problem in two ways:

Use synchronization to protect access to process-global functions.

Do not use process-global functions.

If you choose to implement the synchronization solution, you must ensure
that the code making NI-488.2 calls and examining the NI-488.2 globals
modified by a NI-488.2 call is protected by a synchronization primitive.
For example, each thread might acquire a semaphore before making a
NI-488.2 call and then release the semaphore after examining the NI-488.2
globals modified by the call. For more information about the use of
synchronization primitives, refer to your operating system documentation
about synchronization objects supported by your operating system.

If you choose not to use process-global functions, you can access
per-thread copies of the NI-488.2 global variables using a special set of
NI-488.2 calls. Whenever a thread makes an NI-488.2 call, the driver keeps
a private copy of the NI-488.2 globals for that thread. The following code
shows the set of functions you can use to access these per-thread NI-488.2
global functions:

unsigned long ThreadIbsta();// return thread-specific

Ibsta()

unsigned long ThreadIberr();// return thread-specific

Iberr()

unsigned long ThreadIbcnt();// return thread-specific

Ibcnt()

In your application, instead of accessing the per-process NI-488.2 globals,
substitute a call to get the corresponding per-thread NI-488.2 global.
For example, the following line of code,

if (Ibsta() & ERR)

could be replaced by

if (ThreadIbsta() & ERR)

Advertising