HP-UX HB v13.00 Ch-11 - Software Development

HP-UX Handbook Rev 13.00 Page 28 (of 101)
Chapter 11 Software Development
October 29, 2013
On HP-UX 10.X there were only user threads (also referred to as 1xN), which means that the
kernel has only one thread per process, but the program can handle multiple threads, and it is up
to the process to determine which of its threads should run. The kernel cannot distinguish
between these threads because it only knows one thread, so there is no way for the scheduler to
distribute the threads over multiple CPU's, which means that only one user thread could run at a
time. User threads are also referred to as CMA threads, and the functions needed to make a
program multithreaded are collected in the library libcma.sl.
HP-UX 11.0 introduced the kernel threads (Mx1), which means that the threads are handled by
the kernel now, but each kernel thread can handle only one user thread. If a multithreaded
process is running on a multiprocessor system, the kernel can schedule multiple threads on
different CPU's simultaneously. Kernel threads in HP-UX 11.X conform to the POSIX 1003.1c
standard. That's why the kernel threads are also known as POSIX threads, and the appropriate
library for these threads is libpthread.sl on PA and libpthread.so on IA. On HP-UX
11.X the CMA threads are still available for downward compatibility reasons, but CMA threads
are not compatible to POSIX threads and cannot be used together within one program.
There also exists the so called MxN threads model, which means that each kernel thread can
handle multiple user threads. This model is supported since HP-UX 11.23.
Program Termination
The last action of a program is, of course, to terminate. From the programmers view, programs
can terminate in several ways:
Calling exit() causes the program to terminate regularly. The program's resources are
freed and the process dies. An exit code can be passed to exit(). The exit code can be
checked in the parent process, e.g. with the command "echo $?" in a shell.
Returning explicitly from main() has the same effect as calling exit(). The return
statement can have one argument which will be used as the exit code.
Reaching the end of a function is an implicit return. Reaching the end of main() will exit
the program. In this case the exit code of the program is equal to the return code of the
function that was executed last.
Receiving a signal (see signal(5)) may terminate a process. Some signals cause the
generation of a core file, others don’t. Signals can be sent by the kernel, by the process
itself or by other processes. If the kernel sent a signal, it most likely detected a program
failure, and the signal used by it will cause the generation of a core file. The core file can
be debugged to find out why the program aborted.
exec() also makes a program terminate, but the process stays alive, executing the new
program.
Since some of the above are actually the same, there are only three different ways for a program
to terminate: