Process
Overview (Inside a Linux Process, and Types of Process)
A process is a running
instance of a program. In this article we used two terms ‘program’ and ‘running
instance’. Suppose we run a program simultaneously 5 times, then corresponding
to each instance there will be a process running in the system. So we say that
a process is a “running instance” of a program.
As you already know, you can use ps command to view the processes running on your system. For effective use of the ps command, refer to 7 Practical PS Command Examples for Process Monitoring.
As you already know, you can use ps command to view the processes running on your system. For effective use of the ps command, refer to 7 Practical PS Command Examples for Process Monitoring.
1. Peeping Inside a Process
Now, since we are
clear with what exactly a process is, lets dig a bit deeper to see what a
process consists of. A Unix process can be thought of as a container which
contains:
Program Instructions
Program instructions
are kept in text segments which are executed by CPU. Usually for programs like
text editors which are executed frequently the text segment is shared. This
segment has read only privileges which means that a program cannot modify its
text segment.
Data
Mostly the data is
kept in data segment. Data segment can be classified into initialized data
segment and uninitialized data segment. As the name suggest, initialized data
segment contains those global variables which are initialized before hand while
uninitialized data segment (also known as ‘BSS’ segment) contains uninitialized
global variables. Also, static variables are stored in data segment.
Local variables which
are local to functions are stored on stack. Stack is particular to a function
and besides containing the information about local variables it also contains
information about the address where the flow will return once the execution of
function is done. Stack also contains information about the callers
environment, like some of the machine registers are also stored on stack. A
function which is called allocates memory for its local variables and temporary
variables on stack itself. In case of recursive function an independent stack
for each function call exists.
Then there is data
which is stored on heap. This memory for this data is allocated on runtime on heap
segment. Heap segment is not local to a process but shared across processes.
This is the reason why C programmers worry a lot about memory leaks which are
caused on heap segment and may affect other processes on the system.
Command line arguments and environment
variables
A process also
contains room for storing environment variables and the command line arguments
that we pass to the program. Usually the vector containing the command line
information is stored here and then the address of this vector of information
and number of elements in vector is copied to ‘argv’ and ‘argc’ (the two
arguments to ‘main()’ function).
Besides
the above information, a process also contains information like
§ State of its I/O
§ Its priority and other
control information
One
of the most important control information for a process is the privileges. A
process directly inherits all the privileges of the user who has triggered this
process. For example a process triggered by user who does not have superuser
privileges cannot do stuff that require root privileges while a process
triggered by root can do any thing that it is programmed to do. An exception to
the above rule is where a process can acquire greater privileges than the user
who triggered it if the setuid or setgid bit is set for that particular
process. But we will not go into much detail about it here(refer to the man
pages of setuid and setgid for more information on this).
2. Background and
foreground processes
As
we already discussed that we can start a process by its name in Unix. Like some
standard programs ‘ls’, ‘ps’ etc can be started by just typing their name on
the shell prompt. There are two ways in which we can start a process
§ Starting in foreground
§ Starting in background
Suppose
there is a utility that consumes some time and does a count. Lets say the the
name of the utility is ‘count’ Now to trigger and run the program in
foreground, I run the following command (where ‘count’ is the name of the
binary from the code above) :
$ ./count
Counting done
So
we see that, after running the binary ‘./count’, it took almost 10 seconds
before the output was displayed on stdout and until then the shell was occupied
by this process only. ie You could not perform any other operation on the same
shell. Now, to trigger a process in background, add ‘&’ at the end of the
command:
$ ./count &
[1] 4120
$ # Do some work on shell while the above program is working
in the background
$ Counting done
The
ampersand ‘&’ sign indicates that this process needs to be run as a
background process. By running a background process, we can have access to the
shell for doing any further operations. Like, in the output above, after
running the binary ‘count’ in background, I used a couple of more commands on
the same shell and when the binary ‘count’ was done with its processing, the
output was thrown back on the same shell(the last line). So we can conclude
that by default every process runs in foreground, receives input(if any) from
keyboard and returns output to the user. While a background process is one
which gets disconnected from the keyboard and user can use the same shell to do
more operations.
For
more information on foreground and background processes refer to: How to Manage
UNIX Background Jobs
3. Types of process
So
we see that process is a concept that is fundamental to an operating system.
Almost every activity on an OS takes form of a process to do some stuff. There
are different types of processes running on a system, some of them are :
Child processes
A
process that is created by some other process during run-time. Usually child
processes are created to execute some binary from within an existing process.
Child processes are created using fork() system call. Normally process are made
to run through shell/terminal. In that case the shell becomes the parent and
the executed process becomes the child process. On Unix/Linux each process has
a parent except the init process(we will learn about this later).
Daemon Processes
These
are special processes that run in background. They are system related process
that have no associated terminal. These processes run will root permissions and
usually provide services to processes. As we already know that a daemon process
does not have an attached terminal, well to achieve this the process has to be
detached from the terminal. The ideal way on Linux/Unix to do this is to run a
process through terminal and from within this process create another process
and then terminate the parent process. Since the parent is terminated so now
the child will become independent of the terminal and would be taken over by
init process and hence would become a daemon process. A typical example would
be a mail daemon that waits for the arrival of e-mails and notify when a mail
is received.
Orphan processes
Usually
a process creates a child process (as described above) and when the child
process terminates, a signal is issued to the parent so that parent can do all
the stuff that it is required to do when one of the child gets terminated. But
there are situations when parent gets killed. In that case the child processes
become orphan and then taken under by the init process. Though the init process
takes the ownership of the orphan process but still these process are called as
orphan as their original parents no longer exists.
Zombie process
When
a child process gets terminated or completes its execution, then its entry in
the process table remains until the parent process fetches the status
information of the terminated child. So, until then the terminated process
enters zombie state and is known as zombie process. When a process is
terminated then all the memory and resources associated with the process are
released but the entry of the process in process table exists. A signal
SIGCHILD is send to the parent of the process (that just terminated).
Typically, the handler of this signal in the parent executes a ‘wait’ call that
fetches the exit status of the terminated process and then the entry of this zombie
process from the process table is also removed.
4. The init process
As
we discussed earlier, init process is the 5th stage in the 6 Stage of Linux
Boot Process.
You
would be cognizant of the famous ‘chicken and egg’ theory regarding who came
first. In terms of processes, as each process has a parent process, the same
question can be asked about parent or child process. Well, fortunately there is
an answer here. The answer is the init process that is started as a first
process during boot sequence. That means there is no parent of init process.
Lets verify it, since PID of init is ’1′, we use the ps command :
So
we see from the output that PPID is 0, which means that there is no parent for
this process.
$ ps -l 1
F S UID PID PPID C
PRI NI ADDR SZ WCHAN TTY
TIME CMD
4 S 0
1 0 0 80 0 - 5952 poll_s
? 0:00 /sbin/init
7 Practical PS
Command Examples for Process Monitoring
by SASIKALA on APRIL 12, 2011
Process is a running
instance of a program. Linux is a multitasking operating system, which means
that more than one process can be active at once. Use ps command to find out
what processes are running on your system.
This article explains
7 practical usages of ps command and its options.
To monitor and control the processes, Linux provides lot of commands such as ps, kill, killall, nice, renice and top commands.
To monitor and control the processes, Linux provides lot of commands such as ps, kill, killall, nice, renice and top commands.
1. List Currently Running Processes (ps -ef,
ps -aux)
Its a commonly used
example with a ps command to list down all the process which are currently
running in a machine. The following example shows the options of ps command to
get all the processes.
$
ps -ef
root 26551
5 0 Feb10 ? 00:03:41 [pdflush]
root 26570
5 0 Feb10 ? 00:00:20 [pdflush]
root 30344
3382 0 Feb21 ? 00:00:11 sshd: root@pts/14
root 30365 30344 0 Feb21 pts/14 00:00:02 -bash
root 30393
3382 0 Feb21 ? 00:00:10 sshd: root@pts/15
Where:
§ -e to display all the processes.
§ -f to display full format listing.
In case of BSD
machines, you can use ‘ps -aux’ will give the details about all the process as
shown above.
$
ps -aux
2. List the Process based on the UID and
Commands (ps -u, ps -C)
Use -u option to
displays the process that belongs to a specific username. When you have
multiple username, separate them using a comma. The example below displays all
the process that are owned by user wwwrun, or postfix.
$
ps -f -u wwwrun,postfix
UID PID
PPID C STIME TTY TIME CMD
postfix 7457
7435 0 Mar09 ? 00:00:00 qmgr -l -t fifo -u
wwwrun 7495
7491 0 Mar09 ? 00:00:00 /usr/sbin/httpd2-prefork -f
/etc/apache2/httpd.conf
wwwrun 7496
7491 0 Mar09 ? 00:00:00 /usr/sbin/httpd2-prefork -f
/etc/apache2/httpd.conf
wwwrun 7497
7491 0 Mar09 ? 00:00:00 /usr/sbin/httpd2-prefork -f
/etc/apache2/httpd.conf
wwwrun 7498
7491 0 Mar09 ? 00:00:00 /usr/sbin/httpd2-prefork -f
/etc/apache2/httpd.conf
wwwrun 7499
7491 0 Mar09 ? 00:00:00 /usr/sbin/httpd2-prefork -f
/etc/apache2/httpd.conf
wwwrun 10078
7491 0 Mar09 ? 00:00:00 /usr/sbin/httpd2-prefork -f
/etc/apache2/httpd.conf
wwwrun 10082
7491 0 Mar09 ? 00:00:00 /usr/sbin/httpd2-prefork -f
/etc/apache2/httpd.conf
postfix 15677
7435 0 22:23 ? 00:00:00 pickup -l -t fifo -u
Often ps is used with
grep like “ps -aux | grep command” to get the list of process with the given
command.
But
ps command itself has an option to achieve the same. The following example
shows that all the processes which has tatad.pl in its command execution.
$ ps -f -C tatad.pl
UID PID PPID C
STIME TTY TIME CMD
root 9576 1 0
Mar09 ? 00:00:00
/opt/tata/perl/bin/perl /opt/tata/bin/tatad.pl
root 9577 9576 0
Mar09 ? 00:00:00
/opt/tata/perl/bin/perl /opt/tata/bin/tatad.pl
root 9579 9576 0
Mar09 ? 00:00:00
/opt/tata/perl/bin/perl /opt/tata/bin/tatad.pl
root 9580 9576 0
Mar09 ? 00:00:00
/opt/tata/perl/bin/perl /opt/tata/bin/tatad.pl
root 9581 9576 0
Mar09 ? 00:00:00
/opt/tata/perl/bin/perl /opt/tata/bin/tatad.pl
root 9582 9576 0
Mar09 ? 00:00:00
/opt/tata/perl/bin/perl /opt/tata/bin/tatad.pl
root 12133 9576 0
Mar09 ? 00:00:00
/opt/tata/perl/bin/perl /opt/tata/bin/tatad.pl
Note: We can
create aliases for
ps command to list processes based on commands, users or groups.
3. List the processes
based on PIDs or PPIDs (ps -p, ps –ppid)
Each
process will be assigned with the unique Process ID (PID).
When
you launch some application, it might fork number of processes and each sub
process will have its own PID. So, each process will have its own process id
and parent processid.
For
all the processes that a process forks will have the same PPID (parent process
identifier). The following method is used to get a list of processes with a
particular PPID.
$ ps -f --ppid 9576
UID PID PPID C
STIME TTY TIME CMD
root 9577 9576 0
Mar09 ? 00:00:00
/opt/tata/perl/bin/perl /opt/tata/bin/tatad.pl
root 9579 9576 0
Mar09 ? 00:00:00
/opt/tata/perl/bin/perl /opt/tata/bin/tatad.pl
root 9580 9576 0
Mar09 ? 00:00:00
/opt/tata/perl/bin/perl /opt/tata/bin/tatad.pl
root 9581 9576 0
Mar09 ? 00:00:00
/opt/tata/perl/bin/perl /opt/tata/bin/tatad.pl
root 9582 9576 0
Mar09 ? 00:00:00
/opt/tata/perl/bin/perl /opt/tata/bin/tatad.pl
root 12133 9576 0
Mar09 ? 00:00:00
/opt/tata/perl/bin/perl /opt/tata/bin/tatad.pl
The
following example is to list the processes which has given PID.
$ ps -f -p
25009,7258,2426
UID PID PPID C
STIME TTY TIME CMD
root 2426 4 0
Mar09 ? 00:00:00 [reiserfs/0]
root 7258 1 0
Mar09 ? 00:00:00 /usr/sbin/nscd
postfix 25009 7435 0
00:02 ? 00:00:00 pickup -l -t fifo -u
4. List Processes in a
Hierarchy (ps –forest)
The
example below display the process Id and commands in a hierarchy. –forest is an
argument to ps command which displays ASCII art of process tree. From this
tree, we can identify which is the parent process and the child processes it
forked in a recursive manner.
$ ps -e -o pid,args --forest
468 \_ sshd: root@pts/7
514 | \_
-bash
17484 \_ sshd:
root@pts/11
17513 | \_ -bash
24004 | \_ vi ./790310__11117/journal
15513 \_ sshd:
root@pts/1
15522 | \_ -bash
4280 \_ sshd: root@pts/5
4302 | \_
-bash
Note: You can also
use tree and pstree
command to displays process in a nice tree structure.
5. List elapsed wall
time for processes (ps -o pid,etime=)
If
you want the get the elapsed time for the processes which are currently running
ps command provides etime which provides the elapsed time since the process was
started, in the form [[dd-]hh:]mm:ss.
The
below command displays the elapsed time for the process IDs 1 (init) and
process id 29675.
For
example “10-22:13:29″ in the output represents the process init is running for
10days, 22hours,13 minutes and 29seconds. Since init process starts during the
system startup, this time will be same as the output of the ‘uptime’ command.
# ps -p 1,29675 -o pid,etime=
PID
1 10-22:13:29
29675 1-02:58:46
6. List all threads
for a particular process (ps -L)
You
can get a list of threads for the processes. When a process hangs, we might
need to identify the list of threads running for a particular process as shown
below.
$ ps -C java -L -o
pid,tid,pcpu,state,nlwp,args
PID TID %CPU S NLWP COMMAND
16992 16992 0.0 S 15 ../jre/bin/java
-Djava.ext.dirs=../jre/lib/ext:../lib:../auto_lib -Xdebug -Xnoagent
-Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5006
16992 16993 0.0 S 15 ../jre/bin/java -Djava.ext.dirs=../jre/lib/ext:../lib:../auto_lib
-Xdebug -Xnoagent -Djava.compiler=NONE
-Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5006
16992 16994 0.0 S 15 ../jre/bin/java
-Djava.ext.dirs=../jre/lib/ext:../lib:../auto_lib -Xdebug -Xnoagent -Djava.compiler=NONE
-Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5006
16992 16995 0.0 S 15 ../jre/bin/java
-Djava.ext.dirs=../jre/lib/ext:../lib:../auto_lib -Xdebug -Xnoagent
-Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5006
16992 16996 0.0 S 15 ../jre/bin/java
-Djava.ext.dirs=../jre/lib/ext:../lib:../auto_lib -Xdebug -Xnoagent
-Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5006
16992 16997 0.0 S 15 ../jre/bin/java -Djava.ext.dirs=../jre/lib/ext:../lib:../auto_lib
-Xdebug -Xnoagent -Djava.compiler=NONE
-Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5006
16992 16998 0.0 S 15 ../jre/bin/java
-Djava.ext.dirs=../jre/lib/ext:../lib:../auto_lib -Xdebug -Xnoagent -Djava.compiler=NONE
-Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5006
16992 16999 0.0 S 15 ../jre/bin/java
-Djava.ext.dirs=../jre/lib/ext:../lib:../auto_lib -Xdebug -Xnoagent
-Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5006
16992 17000 0.0 S 15 ../jre/bin/java
-Djava.ext.dirs=../jre/lib/ext:../lib:../auto_lib -Xdebug -Xnoagent
-Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5006
16992 17001 0.0 S 15 ../jre/bin/java -Djava.ext.dirs=../jre/lib/ext:../lib:../auto_lib
-Xdebug -Xnoagent -Djava.compiler=NONE
-Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5006
16992 17002 0.0 S 15 ../jre/bin/java
-Djava.ext.dirs=../jre/lib/ext:../lib:../auto_lib -Xdebug -Xnoagent
-Djava.compiler=NONE
-Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5006
16992 17003 0.0 S 15 ../jre/bin/java
-Djava.ext.dirs=../jre/lib/ext:../lib:../auto_lib -Xdebug -Xnoagent
-Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5006
16992 17024 0.0 S 15 ../jre/bin/java
-Djava.ext.dirs=../jre/lib/ext:../lib:../auto_lib -Xdebug -Xnoagent
-Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5006
16992 15753 0.0 S 15 ../jre/bin/java -Djava.ext.dirs=../jre/lib/ext:../lib:../auto_lib
-Xdebug -Xnoagent -Djava.compiler=NONE
-Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5006
16992 15754 0.0 S 15 ../jre/bin/java
-Djava.ext.dirs=../jre/lib/ext:../lib:../auto_lib -Xdebug -Xnoagent
-Djava.compiler=NONE
-Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5006
-L
option is used to display the list of threads for a process which has the
command given. And it also displays nlwp, which represents number of light
weight processes. In the above example, a total of 15 java threads are running.
7. Finding memory Leak
(ps –sort pmem)
A
memory leak, technically, is an ever-increasing usage of memory by an
application.
With
common desktop applications, this may go unnoticed, because a process typically
frees any memory it has used when you close the application.
However,
In the client/server model, memory leakage is a serious issue, because
applications are expected to be available 24×7. Applications must not continue
to increase their memory usage indefinitely, because this can cause serious
issues. To monitor such memory leaks, we can use the following commands.
$ ps aux --sort pmem
USER PID %CPU
%MEM VSZ RSS TTY
STAT START TIME COMMAND
root 1 0.0
0.0 1520 508 ?
S 2005 1:27
init
inst 1309 0.0
0.4 344308 33048 ? S 2005
1:55 agnt (idle)
inst 2919 0.0
0.4 345580 37368 ? S 2005
20:02 agnt (idle)
inst 24594 0.0 0.4 345068 36960 ? S
2005 15:45 agnt (idle)
root 27645 0.0 14.4
1231288 1183976 ? S 2005
3:01 /TaskServer/bin/./wrapper-linux-x86-32
In
the above ps command, –sort option outputs the highest %MEM at bottom. Just
note down the PID for the highest %MEM usage. Then use ps command to view all
the details about this process id, and monitor the change over time. You had to
manually repeat ir or put it as a cron to a file.
$ ps ev --pid=27645
PID TTY STAT TIME MAJFL TRS DRS RSS %MEM COMMAND
27645 ? S 3:01 0 25 1231262 1183976 14.4
/TaskServer/bin/./wrapper-linux-x86-32
$ ps ev --pid=27645
PID TTY STAT TIME MAJFL TRS DRS RSS %MEM COMMAND
27645 ? S 3:01 0 25 1231262 1183976 14.4
/TaskServer/bin/./wrapper-linux-x86-32
Note: In the above
output, if RSS (resident set size, in KB) increases over time (so would %MEM),
it may indicate a memory leak in the application.
0 comments:
Post a Comment