2.11 Process Termination

Team-FLY

When a process terminates, the operating system deallocates the process resources, updates the appropriate statistics and notifies other processes of the demise. The termination can either be normal or abnormal . The activities performed during process termination include canceling pending timers and signals, releasing virtual memory resources, releasing other process-held system resources such as locks, and closing files that are open . The operating system records the process status and resource usage, notifying the parent in response to a wait function.

In UNIX, a process does not completely release its resources after termination until the parent waits for it. If its parent is not waiting when the process terminates, the process becomes a zombie . A zombie is an inactive process whose resources are deleted later when its parent waits for it. When a process terminates, its orphaned children and zombies are adopted by a special system process. In traditional UNIX systems, this special process is called the init process, a process with process ID value 1 that periodically waits for children.

A normal termination occurs under the following conditions.

  • return from main

  • Implicit return from main (the main function falls off the end)

  • Call to exit , _Exit or _exit

The C exit function calls user -defined exit handlers that were registered by atexit in the reverse order of registration. After calling the user-defined handlers, exit flushes any open streams that have unwritten buffered data and then closes all open streams. Finally, exit removes all temporary files that were created by tmpfile () and then terminates control. Using the return statement from main has the same effect as calling exit with the corresponding status. Reaching the end of main has the same effect as calling exit(0) .

The _Exit and _exit functions do not call user-defined exit handlers before terminating control. The POSIX standard does not specify what happens when a program calls these functions: that is, whether open streams are flushed or temporary files are removed.

The functions exit , _Exit and _exit take a small integer parameter, status , indicating the termination status of the program. Use a status value of 0 to report a successful termination. Programmer-defined nonzero values of status report errors. Example 3.22 on page 77 illustrates how a parent can determine the value of status when it waits for the child. Only the low-order byte of the status value is available to the parent process.

  SYNOPSIS  #include <stdlib.h>    void exit(int status);    void _Exit(int status);  ISO C  
  SYNOPSIS  #include <unistd.h>    void _exit(int status);  POSIX  

The C atexit function installs a user-defined exit handler. Exit handlers are executed on a last-installed-first-executed order when the program returns from main or calls exit . Use multiple calls to atexit to install several handlers. The atexit function takes a single parameter, the function to be executed as a handler.

  SYNOPSIS  #include <stdlib.h>    int atexit(void (*func)(void));  ISO C  

If successful, atexit returns 0. If unsuccessful , atexit returns a nonzero value.

Program 2.10 has an exit handler, showtimes , that causes statistics about the time used by the program and its children to be output to standard error before the program terminates. The times function returns timing information in the form of the number of clock ticks . The showtimes function converts the time to seconds by dividing by the number of clock ticks per second (found by calling sysconf ). Chapter 9 discusses time more completely.

Program 2.10 showtimes.c

A program with an exit handler that outputs CPU usage .

 #include <limits.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/times.h> static void showtimes(void) {    double ticks;    struct tms tinfo;    if ((ticks = (double) sysconf(_SC_CLK_TCK)) == -1)       perror("Failed to determine clock ticks per second");    else if (times(&tinfo) == (clock_t)-1)       perror("Failed to get times information");    else {       fprintf(stderr, "User time:              %8.3f seconds\n",          tinfo.tms_utime/ticks);       fprintf(stderr, "System time:            %8.3f seconds\n",          tinfo.tms_stime/ticks);       fprintf(stderr, "Children's user time:   %8.3f seconds\n",          tinfo.tms_cutime/ticks);       fprintf(stderr, "Children's system time: %8.3f seconds\n",          tinfo.tms_cstime/ticks);    } } int main(void) {    if (atexit(showtimes))  {       fprintf(stderr, "Failed to install showtimes exit handler\n");       return 1;    }     /*  rest of main program goes here */    return 0; } 

A process can also terminate abnormally either by calling abort or by processing a signal that causes termination. The signal may be generated by an external event (like Ctrl-C from the keyboard) or by an internal error such as an attempt to access an illegal memory location. An abnormal termination may produce a core dump, and user-installed exit handlers are not called.

Team-FLY


Unix Systems Programming
UNIX Systems Programming: Communication, Concurrency and Threads
ISBN: 0130424110
EAN: 2147483647
Year: 2003
Pages: 274

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net