DCE for the HP e3000 (B3821-90002)

Programming with Kernel Threads
Writing Threaded Applications
Chapter 5
54
Writing Threaded Applications
The following are hints on writing multithreaded DCE applications:
All DCE applications are multithreaded — When writing DCE applications, keep in
mind, that the DCE runtime software is multithreaded and all DCE applications are
multithreaded; even if the application code itself does not explicitly create threads.
Using non-thread-safe libraries — When making calls to libraries you do not
specifically know to be thread-safe, you must provide your own locking scheme to
prevent multiple threads from executing the same library calls concurrently. While a
given call may appear to be innocuous with respect to threads, it is very difficult to
know exactly what interactions can occur within the library, or with other libraries.
For example, suppose non-thread-safe routines 1 and 2 make a call to routine A (also
non-thread-safe), if routines 1 and 2 use different mutexes to lock their calls to
routine A, then routines 1 and 2 can both get into routine A at the same time
(violating the programmer's attempt to make the calls thread-safe).
Using fork() in a threaded application — fork() is not allowed from a threaded task.
environ is a process-wide resource — Programmers must coordinate threads that use
the putenv() and getenv() interfaces to change and read environ.
Signal mask: a thread-specific resource — The signal mask is a thread-specific
resource; therefore, if one thread manipulates the signal mask, it only affects signals
that specific threads might be interested in (POSIX 1003.4a Draft 3 behavior).
Handling synchronous terminating signals The default behavior of OSF DCE 1.0.2
is to translate synchronous terminating signals into exceptions. If the exceptionis not
caught, the thread that caused the exception is terminated. Any thread that goes
through the terminate code causes the entire task to be terminated.
Establish synchronous signal handlers using sigaction() — The MPE/iX POSIX C
Library supports the following routines for setting up signal handlers:
signal()
sigaction()
Of these routines, only sigaction() is supported in a DCE application. It is used to establish
handlers for synchronous signals on an individual thread basis only.
Asynchronous signals — There is no supported mechanism for establishing signal
handlers for asynchronous signals on MPE/iX.
Cancelling threads blocked on a system call — The HP 3000 Kernel Threads Service
provides a cancellation facility that enables one thread to terminate another. The
cancelled thread normally terminates at a well-defined point. Terminating a thread
that is blocked while executing system code is not possible on MPE/iX; only threads
executing non-system code may be cancelled.
Using waitpid() The waitpid() routine allows the parent thread to specify which child
it cares about by specifying its PID. This call only works for the initial thread;
because children created by any thread within the task are considered children of the
whole task.
Using setjmp and longjmp — Do not use calls to setjmp and longjmp, these routines save
and restore the signal mask and could inadvertently cause a signal that another