Follow us on facebook

Friday 10 May 2013

Intro to Process & types in Linux



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.
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
http://static.thegeekstuff.com/wp-content/uploads/2011/04/pid-300x225.jpg
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, killallnicerenice 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