Mac OS X Unleashed

Mac OS X Unleashed

By John Ray and William C. Ray

Process Management

In Chapter 6, "Native Utilities and Applications," you were introduced to the way that OS X is composed of many different cooperating processes. This is not particular to OS X, but instead is also the norm for Unix. Instead of a monolithic OS and user interface environment, Unix and (even more so) the Mach kernel on which OS X is based both operate as collections of a large number of cooperating programs. These programs create the illusion and functional experience of a seamless interface, but provide considerably more flexibility in the user's ability to modify things to suit his or her particular needs.

For example, with Mac OS, you're used to having a clock in the menu bar, and having the option to turn it on or off and perhaps set the font. This functionality is a built-in part of the OS and user interface. With Unix, if you want a clock, you run a separate program that displays a clock. Because the clock is a program and not an integral part of the OS, it can be any program. By selecting different programs, the clock can be made to appear as any type that you choose, anywhere on the screen that you choose.

It might take a while for you to come to appreciate the flexibility that this "everything is a process" idea of building operating systems provides for you. Monolithic OS and user interface environments have the advantage of being able to guide the user somewhat more strictly. They also are able to "guarantee" some types of responsiveness in ways that can't be done when all the user interface components are controlled by separate programs. Many of the things we will say are advantages of the new Unix environment—such as processes that run and provide some sort of functionality with no user interface (background processes), or programs that start at some pre-specified time—you might think are not so impressive because they were available in earlier versions of Mac OS. It is true that these advantages have been available. But as much as we love the Mac OS, we have to admit that they have been, at best, hacks; attempts to implement what you now have available to you, the Unix way of managing processes.

Listing Processes: ps

The ps command is used for listing the process status report. This is the command-line version of the Process View utility. There are many options to ps, but you might find issuing ps with the following options informative:

ps -aux

The following provides a sample of what to expect the output to look like:

[localhost:/] joray% ps -aux

USER    PID %CPU %MEM      VSZ    RSS  TT  STAT      TIME COMMAND
joray   345  85.1  2.6  89016  20428  ??  R   3619:50.28 /Applications/SETI@hom
root    277   6.1  0.1  51492    920  ??  S     63:19.47 /Library/S@hScreenSave
joray   290   3.0  0.1   5708    728 std  Ss     0:00.32 -tcsh (tcsh)
root    205   3.0  0.1   2420    560  ??  Rs     0:00.95 lookupd
joray    56   0.0  2.6  62568  20160  ??  Ss    20:50.78 /System/Library/CoreSe
root     58   0.0  0.0   1248     84  ??  Ss     1:39.07 update
root     61   0.0  0.0   1268     72  ??  Ss     0:00.00 dynamic_pager -H 40000
root    106   0.0  0.0   1996    316  ??  Ss     0:00.38 autodiskmount -v -a
root    130   0.0  0.1   3280   1048  ??  Ss     0:00.54 configd
root    138   0.0  0.0   1456    228  ??  Ss     0:00.01 ipconfigd
root    175   0.0  0.0   1260    140  ??  Ss     0:00.93 syslogd
root    194   0.0  0.0   1252    116  ??  Ss     0:00.01 portmap
root    197   0.0  0.0   1288    140  ??  Ss     0:00.00 nibindd
root    198   0.0  0.1   1632    484  ??  S      0:00.49 netinfod local (master
root    214   0.0  0.0   1524    276  ??  S<s    0:21.68 ntpd -f /var/run/ntp.d
root    221   0.0  0.2   9800   1560  ??  S      0:34.79 AppleFileServer
root    225   0.0  0.0   1692    256  ??  Ss     0:00.02 DesktopDB
root    230   0.0  0.0   1260    100  ??  Ss     0:00.02 inetd
root    239   0.0  0.0   1248     68  ??  S      0:00.00 nfsiod -n 4
root    240   0.0  0.0   1248     68  ??  S      0:00.00 nfsiod -n 4
root    241   0.0  0.0   1248     68  ??  S      0:00.00 nfsiod -n 4
root    242   0.0  0.0   1248     68  ??  S      0:00.01 nfsiod -n 4
root    251   0.0  0.2   4560   1648  ??  S      0:00.73 DirectoryService
root    256   0.0  0.0   2260    324  ??  Ss     0:00.01 automount -m /Network/
root    268   0.0  0.2   5048   1788  ??  Ss     0:02.36 /System/Library/CoreSe
root    272   0.0  0.0   1532    120  ??  Ss     0:00.73 cron
root    276   0.0  0.0   1248     60  ??  Ss     0:00.00 /Library/S@hScreenSave
joray   279   0.0  0.4  70752   2976  ??  Ss     0:20.96 /System/Library/CoreSe
root    281   0.0  0.1   3000    432  ??  Ss     0:08.09 slpd -f /etc/slpsa.con
joray   285   0.0  0.3  16000   1972  ??  S      0:01.52 /System/Library/CoreSe
joray   286   0.0  3.3 111080  25680  ??  S      0:28.51 /System/Library/CoreSe
joray   287   0.0  0.7  69216   5260  ??  S      0:01.67 /System/Library/CoreSe
joray   288   0.0  0.2  55260   1488  ??  S      0:00.45 /System/Library/CoreSe
joray   289   0.0  0.9  78860   7328  ??  R      0:21.15 /Applications/Utilitie
joray   302   0.0  2.2  89748  17224  ??  S     44:58.58 /Applications/Internet
joray   304   0.0  5.2 117528  41016  ??  R     62:49.21 /System/Library/CoreSe
root    321   0.0  0.0   1312    100  ??  Ss     0:00.00 /usr/libexec/lpd
joray   346   0.0  0.1   5708    700  p2  Ss     0:00.27 -tcsh (tcsh)
joray   376   0.0  0.0   1604    180  ??  Ss     0:00.07 /usr/bin/hdid -f /User
joray   383   0.0  0.8  76460   6096  ??  S      0:07.24 /Applications/TextEdit
joray   595   0.0  0.1   1676    464  p2  S+     0:00.02 vi output-ps
root    280   0.0  0.0      0      0  ??  Zs     0:00.00  (slpdLoad)
root    598   0.0  0.0   1316    284 std  R+     0:00.00 ps -aux
root      1   0.0  0.0   1260    240  ??  SLs    0:00.03 /sbin/init
root      2   0.0  0.0   1276    140  ??  SL     0:14.17 /sbin/mach_init
root     38   0.0  0.1   2676   1080  ??  Ss     0:00.76 kextd
joray    54   0.0  0.4  20816   2796  ??  Ss     0:02.58 /System/Library/Framew

The output from ps using these flags includes the owner of the process (USER), the process ID (PID), the percentage of the CPU (%CPU) and memory (%MEM) being consumed by the process, the virtual size of the memory space used by the program (VSZ) as well as the amount of that size that's resident in main memory (RSS), the controlling terminal (TT = ?? for no terminal), the run state of the process (STAT = R for running, S for short sleep, others), the accumulated CPU time (TIME), and the command that is running (COMMAND). More display options and orderings are available with the ps command, and command options, syntax, and keyword definitions for ps are included in the command documentation table in Table 14.4.

Table 14.4. The Command Documentation Table for ps

ps Displays process status report
ps [-aCcefhjMmrSTuvwx] [-O <fmt>] [-o <fmt>] [-p 
               <pid>] [-t <tty>]
[-U <username>]

ps [-L]
 
-a Includes information about processes owned by others in addition to yours.
-C Changes the way CPU percentage is calculated by using a raw CPU calculation that ignores resident time. This normally has no effect.
-c Changes the command column output to contain just the executable name rather than the full command line.
-e Displays the environment.
-f Shows command line and environment information about swapped-out processes. This is honored only if the user's user ID is 0.
-h Repeats the header information so that there is one header per page of information.
-j Prints information associated with the following keywords: user, pid, ppid, pgid, sess, jobc, state, tt, time, and co m mand.
-l Displays information associated with the following keywords: uid, pid, ppid, cpu, pri, nice, vsz, rss, wchan, state, tt, time, and command.
-M Prints the threads corresponding with each task.
-m Sorts by memory usage, rather than by process ID.
-r Sorts by current CPU usage, rather than by process ID.
-S Changes the way the process time is calculated by summing all exited children to their parent process.
-T Displays information about processes attached to the device associated with standard output.
-u Displays information associated with the following keywords: user, pid, %cpu, %mem, vsz, rss, tt, state, start, time, and command. The -u option implies the -r option.
-v Displays information associated with the following keywords: pid, state, time, sl, re, pagein, vsz, rss, lim, tsiz, %cpu, %mem, and command. The -v option implies the -m option.
-w Uses 132 columns to display information, instead of the default, which is your window size. If the -w option is specified more than once, ps uses as many columns as necessary, regardless of your window size.
-x Displays information about processes without controlling terminals.
-O <fmt> Adds the information associated with the space- or comma-separated list of keywords specified, after the process ID, in the default information displayed. Keywords may be further defined with an = and a string. Keywords further specified in this manner are displayed in the header as specified rather than using the standard header.
-o <fmt> Displays information associated with the space- or comma-separated list of keywords specified. Keywords may be further defined with an = and a string. Keywords further specified in this manner are displayed in the header as specified rather than using the standard header.
-p <pid> Displays information associated with the specified process ID <pid> .
-t <tty> Displays information about processes attached to the specified terminal device <tty> .
-U <username> Displays information about processes belonging to the specified <username> .
-L Lists the set of available keywords.
The following is a list of the definitions of the keywords that some of the options already include. There are more keywords available than are defined here.
%cpu Percentage CPU usage (alias pcpu)
%mem Percentage memory usage (alias pmem)
command Command and arguments
cpu Short-term CPU usage factor (for scheduling)
jobc Job control count
lim Memory use limit
nice Nice value (alias to ni)
pagein Pageins (total page faults)
pgid Process group number
pid Process ID
ppid Parent process ID
pri Scheduling priority
re Core residency time (in seconds; 127 = infinity)
rss Resident set size (real memory)
rsz Resident set size + (text size/text use count) (alias rs-size)
sess Session pointer
sl Sleep time (in seconds; 127 = infinity)
start Time started
state Symbolic process state (alias stat)
tsiz Text size (in kilobytes)
tt Control terminal name (two-letter abbreviation)
uid Effective user ID
user Username (from uid)
vsz Size of process in virtual memory in kilobytes (alias vsize)
wchan Wait channel (as a symbolic name)

Listing Shell Child Processes: jobs

The term jobs and the term processes are frequently used interchangeably when discussing programs running on a Unix machine. But there is also a more specific meaning of jobs that has to do with processes that are run within, or by, a shell process.

Unix processes have the notion of parent and child processes. For example, consider Terminal.app. If you run a shell in a terminal window (which is what you most frequently will do to get access to a shell), the running process that is that shell will be a child of Terminal.app. If you run a process in the shell, such as ls, or any other commands we discuss in this book, the process that is that command will be a child of the shell. Likewise, the shell will be the parent of the ls command run in it, and Terminal.app will be the parent of the shell. Terminal.app itself in this case will most likely be the child of the OS X Finder, and the Finder will be the child of whatever process controls OS X logins. Every process in this way can trace its execution lineage back to the ancestor of all executing programs /sbin/init, which will have process ID 1.

Therefore, a user's jobs refers to all processes running on a machine that belong to a particular user. Shell jobs, on the other hand, refer to processes that are children of (that is, were run by) a particular running instance of a shell.

The jobs command displays current processes that are children of the shell where the command is issued. This might not make much sense just yet because we haven't introduced any way for you to run a command and have it execute to completion before returning to the command prompt, but we will cover this material shortly. The jobs command gives you the ability to find out what jobs are present and what state they are in. For example, the shell shown in the following output has three jobs running in the background, and one job that is suspended:

localhost ray 160> jobs

     [1]      Running                       ./aaa.csh
     [2]  -   Running                       ./bbbb.csh
     [3]      Running                       ./test.csh
     [4]  +   Suspended                     ./test2.csh

Suspended jobs are jobs that are not executing for one reason or another. In this case, the suspended job was stopped with the Ctrl+Z shell key sequence discussed in Chapter 12, "Introducing the BSD Subsystem,"and is waiting for the user to resume it, send it to the background, or kill it off.

The + and - characters indicate the most current job, and the previously most current job, respectively.

The command documentation for jobs in Table 14.5 also includes information on how a job may be referenced, based on the output of jobs, for use in other job-control commands.

Table 14.5. The command Documentation Table for jobs

jobs Displays the table of current jobs.
jobs [-l]  
-l Lists jobs in long format. This includes the job number and its associated process ID.
After you know what jobs belong to the current shell, there are several ways to refer to a job. % introduces a job name. Job number 1 is %1. An unambiguous string of characters at the beginning of the name can be used to refer to a job; the form is % <first-few-characters-of-job> . An unambiguous string of characters in the job name can also be used to refer to a job; for example, the form %? <text-string> specifies a job whose name contains <text-string> .
Output pertaining to the current job is marked with +; output from a previous job, -. %+, %, and %% refer to the current job. %- refers to the previous job.

Backgrounding Processes: bg

The bg command backgrounds a suspended job. The process continues, only in the background. The most noticeable effect for the user is the return of the command prompt. Backgrounding processes is particularly useful for commands and programs that do not produce command-line output. Although the user's prompt returns, the process continues. It does not make sense to background something like ls, which is trying to show you output to the terminal. On the other hand, backgrounding the process responsible for a long cp or compress can be very convenient. The usual method for suspending a running process is to press Ctrl+Z, which stops, but does not kill, the process. For example:

localhost ray 185> jobs

     [1]  - Running                       ./aaa.csh
      [4]  + Running                       ./test.csh
localhost ray 186> ./test2.csh
^Z

      [1]      468 Running                       ./aaa.csh
      [4]  -   504 Running                       ./test.csh
      [5]  +   635 Suspended                     ./test2.csh
localhost ray 187> jobs

     [1]    Running                       ./aaa.csh
     [4]  - Running                       ./test.csh
     [5]  + Suspended                     ./test2.csh

localhost ray 188> bg

     [5]    ./test2.csh &
     /Users/ray

localhost ray 189>
localhost ray 189> jobs

     [1]  - Running                       ./aaa.csh
     [4]  + Running                       ./test.csh
     [5]    Running                       ./test2.csh

When stopped with Ctrl+Z, the shell automatically tells me the current list of jobs, and includes their process IDs for convenience.

If there were multiple suspended jobs, I could pick which one to send to the background, by the use of an optional job specifier, as shown in the documentation for the bg command in Table 14.6.

Table 14.6. The Command Documentation Table for bg

bg Backgrounds a job
bg [%job> ...]

%<job>%

bg
 
Backgrounds the specified jobs, or if no argument is given, the current job, and continues as though each has stopped. <job> may be any acceptable form described in jobs.

Backgrounding Processes with &

Processes can also be put in the background by the use of the & symbol at the end of the command line. Simply add this symbol to the end of any command line, and the resulting process will be run in the background automatically.

localhost ray 190> jobs

     [1]  - Running                       ./aaa.csh
     [4]  + Running                       ./test.csh
     [5]    Running                       ./test2.csh

localhost ray 191> ./bbbb.csh  &

     [6] 691
      /Users/ray

localhost ray 192>
localhost ray 192> jobs

     [1]  - Running                       ./aaa.csh
     [4]  + Running                       ./test.csh
     [5]    Running                       ./test2.csh
     [6]    Running                       ./bbbb.csh

When a job is put into the background using the & suffix for a command line, it automatically prints out its job number and process ID.

Foregrounding Processes: fg

The command fg returns a job to the foreground, where it continues to run. The command may be either a background job or a suspended job.

localhost ray 207> jobs

     [1]  - Running                       ./aaa.csh
     [5]  + Running                       ./test2.csh

localhost ray 208> fg %1

     ./aaa.csh

Documentation for fg is in the command table, Table 14.7.

Table 14.7. The Command Documentation Table for fg

fg Foregrounds a job
fg [%<job>...]

%<job>

fg
 
Brings the specified jobs (or, if no argument is given, the current job) to the foreground, continuing each as though it had stopped. <job> may be any acceptable form as described in jobs.

Stopping Processes, Sending Signals: kill

The kill command sends a signal to a process or terminates a process. It is most commonly used in conjunction with ps, which provides the process ID of the process to which you want to send a signal.

You will probably most often use this command either to terminate a process, or to send a hang up signal (HUP) to force a process to reread its configuration file.

The syntax that you will probably most often use is one of the following forms:

kill -9 <pid>

kill -HUP <pid>

In the first example, the -9 sends a definite termination signal to the process specified. In the second example, the -HUP sends a hangup signal to a process, which then rereads its configuration file and starts over. You will see at least one example of this later in the book.

The command documentation table for kill is shown in Table 14.8.

Table 14.8. The Command Documentation Table for kill

kill Sends a signal to a process or terminates a process
kill [-<signal>] %<job> | <pid>

kill -l
-l Lists the signal names
<signal> Specifies which signal to send to a process. If <signal> is not specified, the TERM (terminate) signal is sent. <signal> may be a number or name.
%<job> Specifies the job that should receive a signal.
<pid> Specifies the process ID that should receive a signal. The process ID can be determined by running ps.
Signal KILL (9) is a sure way to kill a process. Signal HUP is another common signal to send to a process. You might want to send a HUP signal to a process to get it to reread its configuration file.

Listing Resource-Consuming Processes: top

The top command displays system usage statistics, particularly of those processes making the most use of system resources. Processes are displayed at one-second intervals. It can be useful for diagnosing unusual behavior with a process. It is worthwhile to run top from time to time so that you learn what the typical behavior for your system is.

When top is displaying processes, it takes over your screen. You can quit the display by pressing the Q key. The following is a sample of what top output looks like:

Processes:  41 total, 3 running, 38 sleeping... 102 threads            10:52:23
Load Avg:  1.50, 2.01, 1.99     CPU usage:  89.0% user, 11.0% sys, 0.0% idle
SharedLibs: num =   71, resident = 14.9M code, 1.05M data, 3.62M LinkEdit
MemRegions: num = 1544, resident = 39.0M + 5.67M private, 26.6M shared
PhysMem:  46.5M wired, 30.6M active, 84.4M inactive,  161M used,  607M free
VM: 1.01G + 38.9M   7300(1) pageins, 0(0) pageouts

  PID COMMAND      %CPU   TIME   #TH #PRTS #MREGS RPRVT  RSHRD  RSIZE  VSIZE
  295 top          7.3%  0:00.80   1    19    14   172K   224K   392K  1.31M
  290 tcsh         0.0%  0:00.14   1    17    14   260K   460K   700K  5.57M
  289 Terminal     0.9%  0:01.23   4    76    58  1.40M  3.86M  4.49M+ 73.8M+
  287 ProcessVie   0.0%  0:01.07   2    67    51  1.11M  4.43M  4.57M  73.7M
  286 SETI@home_  88.1%  3:04.39   3    97   131  17.3M  4.32M  20.1M  87.3M
  285 DocklingSe   0.0%  0:00.39   1    56    32   428K  1.53M  1.34M  53.7M
  284 Dock         0.0%  0:00.67   2    93    87  4.18M  3.12M  5.62M  68.2M
  283 Finder       0.0%  0:06.18   3    86   230  10.7M  12.4M  18.2M  98.0M
  282 pbs          0.0%  0:01.52   3    84    51   564K  1.28M  1.87M  15.6M
  278 slpd         0.0%  0:00.03   4    21    19   124K   320K   420K  2.93M
  276 loginwindo   0.0%  0:01.23   2    89    65  1.22M  2.51M  2.90M  69.1M
  274 S@hScreenS   0.9%  0:03.47   1    48    26   364K  1.01M   924K  50.3M
  273 SETI@homeI   0.0%  0:00.00   1    10    12    44K   192K    64K  1.22M
  269 cron         0.0%  0:00.00   1    10    14    84K   220K   132K  1.50M
  265 SecuritySe   0.0%  0:00.04   2    24    27   256K  1020K  1.23M  4.43M

The command documentation table for top is shown in Table 14.9.

Table 14.9. The Command Documentation Table for top

top Displays system usage statistics
top [-u] [-w] [-k] [-s <interval>] [-e | -d | -a] [-l <samples>]
[<number>]

top
-u Sorts by CPU usage and displays usage starting with the highest usage.
-w Generates additional columns of output data. The additional columns include VPRVT and the delta information for #PRTS, RSHRD, RSIZE, and VSIZE.
-k Causes top to traverse and report the memory object map for pid 0 (kernel task). This option is optional because it is expensive to traverse the object maps, as the kernel task may have a large number of entries.
-s <interval> Samples processes at the specified <interval> . Default is one-second intervals.
-e Switches to event counting mode where counts reported are absolute counters. Options -w and -k are ignored.
-d Switches to an event counting mode where counts are reported as deltas relative to the previous sample. Options -w and -k are ignored.
-a Switches to an event counting mode where counts are reported as cumulative counters relative to when top was launched. Options -w and -k are ignored.
-l <samples> Switches from default screen mode to a logging mode suitable for saving the output to a file. If <samples> is specified, top samples the number of samples specified before exiting. The default is 1.
<number> Limits the number of processes displayed to <number> .
Pressing the Q key causes top to exit immediately.
Columns displayed in default data mode:
PID Unix process ID
COMMAND Unix command name
%CPU Percentage of CPU used (kernel and user)
TIME Absolute CPU consumption (min:secs.hundredths)
#TH Number of threads
#PRTS (delta) Number of MACH ports
#MERG Number of memory regions
VPRVT (-w only) Private address space currently allocated
RPRVT (delta) Resident shared memory (as represented by the resident page count of each shared memory object)
RSHRD (delta) Total resident memory (real pages that this process currently has associated with it; some may be shared by other processes)
VSIZE (delta) Total address space currently allocated (including shared)
Columns displayed in event counting modes:
PID Unix process ID
COMMAND Unix command name
%CPU Percentage of CPU used (kernel and user)
TIME Absolute CPU consumption (min:secs.hundredths)
FAULTS Number of page faults
PAGEINS Number of requests for pages from a pager
COW_FAULTS Number of faults that caused a page to be copied
MSGS_SENT Number of mach messages sent by the process
MSGS_RCVD Number of mach messages received by the process
BSDSYSCALL Number of BSD system calls made by the process
MACHSYSCALL Number of MACH system calls made by the process
CSWITCH Number of context switches to this process

+ Share This