As defined earlier, a process is an instance of a running program. Each time a program is run, a process is created (typically) with the same name as the program itself. Processes have the concept of a lifetime associated with them. Processes come to life, or are said to be born as a program is loaded and begins execution. Processes remain alive while the program continues execution (processes, however can have different states of life). Processes ceast to exist and are said to die as the running program terminates (either normally or abnormally).
As was also mentioned, processes have a parent which created them. Similarly, when a process is created, it is created as a child process, with the process responsible for its creation being its parent. When a process creates a child process, it is said to have spawned a child. Every process on a Unix system must have a parent (again, except the very first one), since "orphaned" processes are not allowed. Also, all processes on a Unix system can be linked to the single initial process.
Each process will have many attributes associated with it. A processes attributes are stored in a structure memory which is called a Process Control Block, or PCB. Each indiviual process will have a PCB associated with it. Some of these attributes include PID, PPID, priority, ownership, state, etc. The diagram below shows the parent-child relationship, as well as the PCB of each process.
To examine the actual status of processes on a Unix system, the ps command will be used along with several of its options. By simply runnig the ps command without any options, one can observe the following:
$ ps [Enter] PID TTY TIME CMD 30758 pts/0 00:00:00 ksh 30891 pts/0 00:00:00 psIn this output, two running programs are listed, the ksh (parent) process and the ps (child) process. Along with this is displayed the PID of each as well as the TTY (connected terminal id) and the cumulative execution time. Only two are listed since these two processes are the only two belonging to this user id (uid) and this TTY.
A bit more information can be viewed using the -x option with ps (note that not all options will work on all Unix implementations; see the ps man page on your system) as follows:
$ ps -x [Enter] PID TTY STAT TIME CMD 30758 pts/0 S 0:00 -ksh 31043 pts/0 R 0:00 ps -xIn this output, we see all information from above as well as an additional field labeled STAT which indicates the process status. What do the S and R status values indicate? Recall what happens to the parent when a child process executes. In general, the possible process states are:
D uninterruptible sleep (usually IO) R runnable (on run queue) S sleeping T traced or stopped Z a defunct ("zombie") processAlso notice that the PID of the ksh processes is the same in both output displays (30758) but the two ps command PIDs differ (30891 & 31043). Can you explain this?
All of the processes on a Unix system can be listed using several options as follows:
$ ps -eaf [Enter] UID PID PPID C STIME TTY TIME CMD root 1 0 0 Oct12 ? 00:00:04 init root 2 1 0 Oct12 ? 00:00:00 [keventd] root 3 1 0 Oct12 ? 00:00:00 [kapm-idled] root 4 0 0 Oct12 ? 00:00:00 [ksoftirqd_CPU0] root 5 0 0 Oct12 ? 00:00:00 [kswapd] root 6 0 0 Oct12 ? 00:00:00 [kreclaimd] root 7 0 0 Oct12 ? 00:00:00 [bdflush] root 8 0 0 Oct12 ? 00:00:00 [kupdated] root 9 1 0 Oct12 ? 00:00:00 [mdrecoveryd] root 13 1 0 Oct12 ? 00:00:01 [kjournald] root 88 1 0 Oct12 ? 00:00:00 [khubd] root 193 1 0 Oct12 ? 00:00:00 [kjournald] root 649 1 0 Oct12 ? 00:00:00 syslogd -m 0 ntp 749 1 0 Oct12 ? 00:00:00 ntpd -U ntp root 785 749 0 Oct12 ? 00:00:00 ntpd -U ntp root 805 1 0 Oct12 ? 00:00:02 /usr/sbin/sshd lp 864 1 0 Oct12 ? 00:00:00 lpd Waiting root 892 1 0 Oct12 ? 00:00:00 sendmail: accepting connections root 939 1 0 Oct12 ? 00:00:00 gpm -t ps/2 -m /dev/mouse root 957 1 0 Oct12 ? 00:00:00 crond xfs 1027 1 0 Oct12 ? 00:00:00 xfs -droppriv -daemon daemon 1063 1 0 Oct12 ? 00:00:00 /usr/sbin/atd root 1086 1 0 Oct12 tty1 00:00:00 /sbin/mingetty tty1 root 1087 1 0 Oct12 tty2 00:00:00 /sbin/mingetty tty2 root 1088 1 0 Oct12 tty3 00:00:00 /sbin/mingetty tty3 root 1089 1 0 Oct12 tty4 00:00:00 /sbin/mingetty tty4 root 1090 1 0 Oct12 tty5 00:00:00 /sbin/mingetty tty5 root 1091 1 0 Oct12 tty6 00:00:00 /sbin/mingetty tty6 root 30757 805 0 15:21 ? 00:00:00 /usr/sbin/sshd mthomas 30758 30757 0 15:21 pts/0 00:00:00 -ksh mthomas 30845 30758 0 16:41 pts/0 00:00:00 ps -eafNotice that the owner of most of these processes is root. Notice also that both the PID and the PPID are listed in this output. Looking at this output dissected, one should be able to trace the ancestry of the ps command:
$ ps -eaf [Enter] UID PID PPID C STIME TTY TIME CMD root 1 0 0 Oct12 ? 00:00:04 init . . root 805 1 0 Oct12 ? 00:00:01 /usr/sbin/sshd . . root 30757 805 0 15:21 ? 00:00:00 /usr/sbin/sshd mthomas 30758 30757 0 15:21 pts/0 00:00:00 -ksh mthomas 30845 30758 0 15:29 pts/0 00:00:00 ps -eafYou can see the process id of the ps process is 30845, and its parent is PID 30758. Process number 30758 is the ksh process, and its parent is process 30757. Process 30757 is sshd (a secure shell client 1) and its parent is PID 805. Process 805 is sshd (a secure shell server) whose parent is PID 1, which leads us to our venerable grandparent process, init. 2
There is another way to view the system process hierarchy, and that is using the command pstree. This command gives you a top-down view of the process tree as follows:
$ pstree [Enter] init-+-apmd |-atd |-crond |-gpm |-kapm-idled |-keventd |-khubd |-2*[kjournald] |-klogd |-lpd |-mdrecoveryd |-6*[mingetty] |-ntpd---ntpd |-sendmail |-sshd---sshd---ksh---pstree |-syslogd |-xfs `-xinetdThis is an alphabetical listing, with all processes being connected to init. Make sure you can identify the parent-child connection from the pstree command as describe in the ps output above.
1 This connection is being made from a Win PC with a ssh client to a Linux installation via a ssh server connection, thus the 2 ssh processes.
2 As mentioned previously, since the original publication of this e-text, the init process has been replaced in some Linux distributions by the systemd process, also having PID 1. This has become somewhat controversial, and has been described as a violation of the Unix philosophy. More on the systemd process here. [Wikipedia contributors]
The fork system call creates a new process by duplicating the calling process (i.e. the parent). This new process differs from the parent process only in its new PID and the PPID pointing back to the parent. Following a fork system call, 2 processes will co-exist (the parent and the child). Often coupled with fork is the exec system call. The exec system call immediately replaces or overlays the newly created child process (when used with fork), which includes inheriting the process id of the process it replaced. The standard method for creating a new process is to use fork to make a copy of the existing process, then using exec to overwrite the copy with the new (child) process. This is commonly refered to as the fork-exec call sequence.
Following are examples of fork and exec in action. In the first example, initially a Korn shell is present, displayed by the ps command. Next the bash command is entered, which uses a fork call to clone the (ksh) parent, then overwriting the child (via exec) with the bash process, resulting in both a Korn shell parent and a bash shell child. Thus when the exit command is entered the child dies leaving only the Korn shell parent.
$ ps -x PID TTY STAT TIME COMMAND 7540 pts/0 S 0:00 -ksh 7573 pts/0 R 0:00 ps -x $ bash $ ps -x PID TTY STAT TIME COMMAND 7540 pts/0 S 0:00 -ksh 7574 pts/0 S 0:00 bash 7586 pts/0 R 0:00 ps -x $ exit exit $ ps -x PID TTY STAT TIME COMMAND 7540 pts/0 S 0:00 -ksh 7594 pts/0 R 0:00 ps -xIn the second example, the same Korn shell is present as above. When the bash shell is exec'd (without a fork), this leaves only a bash process and no Korn shell process. Note the PID of the new bash shell is the same as the overwritten Korn shell.
$ ps -x PID TTY STAT TIME COMMAND 7540 pts/0 S 0:00 -ksh 7599 pts/0 R 0:00 ps -x $ exec bash $ ps -x PID TTY STAT TIME COMMAND 7540 pts/0 S 0:00 bash 7611 pts/0 R 0:00 ps -x
Terminate a process
If a process is running, and the terminal (i.e. tty) that started its execution is available, the simple key sequence to terminate a process is [Ctrl-c]. This will result in the process being immediately terminated.
If there is not access to the starting tty, and you wish to terminate a process (i.e. remotely), the command to do this is:
kill signal pidwhere the signal is optional.The signal can be an actual Unix signal or can be a numeric representation of a signals value. Some of the common named Unix signals and their corresponding numeric ids are:
SIGHUP 1 SIGINT 2 SIGQUIT 3 SIGTRAP 5 SIGKILL 9 SIGTERM 15Thus, you can terminate a process in the following ways:
kill pid # default signal of SIGTERM kill -KILL pid # use of SIGKILL signal kill -9 pid # also KILL signalSome processes will ignore certain signals, for example, if you try to kill your shell with the default TERM signal, this will be ignored by the shell. Typically when you want to kill a process, you really want to terminate it and the -9 signal is the easiest to remember.
Suspend a process
Suspending a process is done with key sequence [Ctrl-z]. Once this command is entered, the process becomes a suspended (stopped) process, as follows:
$ vi foo [Enter] [Ctrl-z] [1] + Stopped vi foo $ ps -x [Enter] PID TTY STAT TIME COMMAND 2876 pts/0 S 0:00 -ksh 2941 pts/0 T 0:00 vi foo 2946 pts/0 R 0:00 ps -xMove a process/job to the background
To move a suspended (stopped) process to the background, you use the bg command. This will allow the suspended job to execute in the background.
Move a background process/job to the foreground
To move a background process to the foreground, you use the fg command. This will continue the execution of the job in the foreground.
Start a job to execute as a background process.
To start a job in the background, you simply follow the command with the ampersand (&) character. This is analogous to suspending the job and issuing the bg command. When a job is started in the background, control of the terminal will return immediately. This is especially useful when starting programs that run in their own GUI based window, such as browsers and hardware monitors, for example:
$ firefox & [Enter]List active jobs
To list active jobs, you simply use the jobs command. The jobs command will show all active jobs for the current user.
$ jobs [Enter] [1] + Running du / [2] - Running loop_program [3] - Running cc configs.cNotice the numbers enclosed within the brackets, []. This indicates the order of the job, that is the nth job in the job queue. To operate on a specific job, specify the job number preceded by the percent character. Thus to bring the 2nd job to the foreground, the command would be:
$ fg %2 [Enter]
©2019, Mark A. Thomas. All Rights Reserved.