OSF DCE Application Development Guide--Core Components
Programming with Threads
In a multithreaded program, signals cannot be used in a modular way because, on most
current UNIX implementations, signals are inherently a process construct. There is only
one instantiation of each signal and of each signal handler routine for all of the threads
in an application. If one thread handles a particular signal in one way, and a different
thread handles the same signal in a different way, then the thread that installs its signal
handler last handles the signal. This applies only to asynchronously generated signals;
synchronous signals can be handled on a per-thread basis using the DCE Threads
sigaction( ) jacket.
Do not use asynchronous programming techniques in conjunction with threads,
particularly those that increase parallelism such as using timer signals and I/O signals.
These techniques can be complicated. They are also unnecessary because threads
provide a mechanism for parallel execution that is simpler and less prone to error where
concurrence can be of value. Furthermore, most of the threads routines are not
supported for use in interrupt routines (such as signal handlers), and portions of runtime
libraries cannot be used reliably inside a signal handler.
8.3 Nonthreaded Libraries
As programming with threads becomes common practice, you need to ensure that
threaded code and nonthreaded code (code that is not designed to work with threads)
work properly together in the same application. For example, you may write a new
application that uses threads (for example, an RPC server), and link it with a library that
does not use threads (and is thus not thread-safe). In such a situation you can do one of
the following:
• Work with the nonthreaded software.
• Change the nonthreaded software to be thread-safe.
8.3.1 Working with Nonthreaded Software
Thread-safe code is code that works properly in a threaded environment. To work with
nonthread-safe code, associate the global lock with all calls to such code.
You can implement the lock on the side of the routine user or the routine provider. For
example, you can implement the lock on the side of the routine user if you write a new
application like an RPC server that uses threads, and you link it with a library that does
not. Or, if you have access to the nonthreaded code, the locks can be placed on the side
of the routine provider, within the actual routine. Implement the locks as follows:
1. Associate one lock, a global lock, with execution of such code.
2. Require all of your threads to lock prior to execution of nonthreaded code.
3. Perform an unlock when execution is complete.
124245 Tandem Computers Incorporated 8−9