初探Linux進程管理機制

轉至:http://ixdba.blog.51cto.com/2895551/543737java

一 、進程的概念和分類
1.進程的概念

 Linux是一個多用戶多任務的操做系統。多用戶是指多個用戶能夠在同一時間使用同一個linux系統;多任務是指在Linux下能夠同時執行多個任務,更詳細的說,linux採用了分時管理的方法,全部的任務都放在一個隊列中,操做系統根據每一個任務的優先級爲每一個任務分配合適的時間片,每一個時間片很短,用戶根本感受不到是多個任務在運行,從而使全部的任務共同分享系統資源,所以linux能夠在一個任務還未執行完時,暫時掛起此任務,又去執行另外一個任務,過一段時間之後再回來處理這個任務,直到這個任務完成,才從任務隊列中去除。這就是多任務的概念。
上面說的是單CPU多任務操做系統的情形,在這種環境下,雖然系統能夠運行多個任務,可是在某一個時間點,CPU只能執行一個進程,而在多CPU多任務的操做系統下,因爲有多個CPU,因此在某個時間點上,能夠有多個進程同時運行。
進程的的基本定義是:在自身的虛擬地址空間運行的一個獨立的程序,從操做系統的角度來看,全部在系統上運行的東西,均可以稱爲一個進程。
須要注意的是:程序和進程是有區別的,進程雖然有程序產生,可是它並非程序,程序是一個進程指令的集合,它能夠啓用一個或多個進程,同時,程序只佔用磁盤空間,而不佔用系統運行資源,而進程僅僅佔用系統內存空間,是動態的、可變的,關閉進程,佔用的內存資源隨之釋放。
例如,用戶在linux上打開一個文件、就會產生一個打開文件的進程,關閉文件,進程也隨機關閉。若是在系統上啓動一個服務,例如啓動tomcat服務,就會產生一個對應的java的進程。而若是啓動apache服務,就會產生多個httpd進程。node

2.進程的分類
按照進程的功能和運行的程序分類,進程可劃分爲兩大類:
 系統進程:能夠執行內存資源分配和進程切換等管理工做;並且,該進程的運行不受用戶的干預,即便是root用戶也不能干預系統進程的運行。
 用戶進程:經過執行用戶程序、應用程序或內核以外的系統程序而產生的進程,此類進程能夠在用戶的控制下運行或關閉。
針對用戶進程,又能夠分爲交互進程、批處理進程和守護進程三類。
 交互進程:由一個shell終端啓動的進程,在執行過程當中,須要與用戶進行交互操做,能夠運行於前臺,也能夠運行在後臺。
 批處理進程:該進程是一個進程集合,負責按順序啓動其餘的進程。
 守護進程:守護進程是一直運行的一種進程,常常在linux系統啓動時啓動,在系統關閉時終止。它們獨立於控制終端而且週期性的執行某種任務或等待處理某些發生的事件。例如httpd進程,一直處於運行狀態,等待用戶的訪問。還有常常用的crond進程,這個進程相似與windows的計劃任務,能夠週期性的執行用戶設定的某些任務。mysql

3.進程的屬性
(1)進程的幾種狀態
進程在啓動後,不必定立刻開始運行,於是進程存在不少種狀態。
 可運行狀態:處於這種狀態的進程,要麼正在運行、要麼正準備運行。
 可中斷的等待狀態:這類進程處於阻塞狀態,一旦達到某種條件,就會變爲運行態。同時該狀態的進程也會因爲接收到信號而被提早喚醒進入到運行態。
 不中斷的等待狀態:與「可中斷的等待狀態」含義基本相似,惟一不一樣的是處於這個狀態的進程對信號不作響應。
 僵死狀態:也就是僵死進程,每一個進程在結束後都會處於僵死狀態,等待父進程調用進而釋放資源,處於該狀態的進程已經結束,可是它的父進程尚未釋放其系統資源。
 暫停狀態:代表此時的進程暫時中止,來接收某種特殊處理,
(2)進程之間的關係
在linux系統中,進程ID(用PID表示)是區分不一樣進程的惟一標識,它們的大小是有限制的,最大ID爲32768,用UID和GID分別表示啓動這個進程的用戶和用戶組。全部的進程都是PID爲1的init進程的後代,內核在系統啓動的最後階段啓動init進程,於是,這個進程是linux下全部進程的父進程,用PPID表示父進程。
下面是經過ps命令輸出的sendmail進程信息:
[root@localhost ~]# ps -ef|grep  sendmail
UID       PID     PPID  C   STIME  TTY        TIME               CMD
root      3614     1    0   Oct23   ?        00:00:00  sendmail: accepting connections
相對於父進程,就存在子進程,通常每一個進程都必須有一個父進程,父進程與子進程之間是管理與被管理的關係,當父進程中止時,子進程也隨之消失,可是子進程關閉,父進程不必定終止。
若是父進程在子進程退出以前就退出,那麼全部子進程就變成的一個孤兒進程,若是沒有相應的處理機制的話,這些孤兒進程就會一直處於僵死狀態,資源沒法釋放,此時解決的辦法是在啓動的進程內找一個進程做爲這些孤兒進程的父進程,或者直接讓init進程做爲它們的父進程,進而釋放孤兒進程佔用的資源。linux

2、 進程的監控與管理
         Linux下,監控和管理進程的命令有不少,下面咱們以ps、top、pstree、lsof四個最經常使用的指令介紹若是有效的監控和管理linux下的各類進程。
web

2.1 利用ps命令監控系統進程
         ps是linux下最經常使用的進程監控命令,關於ps命令的語法和使用選項,咱們在第四章已經有了詳細的講解,這裏重點講述如何利用ps指令監控和管理系統進程。
請看下面的示例:
下面是apache進程的輸出信息
[root@localhost ~]#ps -ef | grep httpd
UID       PID  PPID   C STIME TTY         TIME     CMD
nobody    7272 26037  0 Nov06  ?        00:00:00 /apache2/bin/httpd -k start
nobody    7274 26037  0 Nov06  ?        00:00:00 /apache2/bin/httpd -k start
nobody    7400 26037  0 Nov06  ?        00:00:00 /apache2/bin/httpd -k start
nobody    7508 26037  0 00:09  ?        00:00:00 /apache2/bin/httpd -k start
nobody    7513 26037  0 00:09  ?        00:00:00 /apache2/bin/httpd -k start
nobody    7515 26037  0 00:09  ?        00:00:00 /apache2/bin/httpd -k start
nobody   11998 26037  0 11:14  ?        00:00:00 /apache2/bin/httpd -k start
nobody   12941 26037  0 16:25  ?        00:00:00 /apache2/bin/httpd -k start
nobody   12979 26037  0 16:44  ?        00:00:00 /apache2/bin/httpd -k start
root     26037  1     0 Oct23  ?        00:00:00 /apache2/bin/httpd -k start        
          其中,UID是用戶的ID標識號,PID是進程的標識號,PPID表示父進程,STIME表示進程的啓動時間,TTY表示進程所屬的終端控制檯,TIME表示進程啓動後累計使用的CPU總時間,CMD表示正在執行的命令。
         從中能夠清楚的看出,父進程和子進程的對應關係, PPID爲26037的全部進程均爲子進程,而PID爲26037的進程是全部子進程的父進程,子進程由nobody用戶啓動,而父進程由root用戶啓動,父進程對應的PPID爲1,即父進程同時爲init進程的子進程。
         其實也能夠經過下面的指令方式查看子進程與父進程的對應關係,請看以下操做:
[root@localhost ~]# ps auxf | grep httpd
USER      PID  %CPU %MEM    VSZ  RSS  TTY STAT  START   TIME   COMMAND
root     26037  0.0  0.1   6316  2884  ?   Ss   Oct23   0:00 /apache2/bin/httpd -k start
nobody    7272  0.0  0.1   7016  3740  ?   S    Nov06   0:00  \_ /apache2/bin/httpd -k start
nobody    7274  0.0  0.1   7016  3704  ?   S    Nov06   0:00  \_ /apache2/bin/httpd -k start
nobody    7400  0.0  0.1   7012  3676  ?   S    Nov06   0:00  \_ /apache2/bin/httpd -k start
nobody    7508  0.0  0.1   7012  3732  ?   S    00:09   0:00  \_ /apache2/bin/httpd -k start
nobody    7513  0.0  0.1   7012  3700  ?   S    00:09   0:00  \_ /apache2/bin/httpd -k start
nobody   12979  0.0  0.1   7016  3684  ?   S    16:44   0:00  \_ /apache2/bin/httpd -k start
nobody   12980  0.0  0.1   7012  3652  ?   S    16:44   0:00  \_ /apache2/bin/httpd -k start
nobody   12982  0.0  0.1   7016  3664  ?   S    16:44   0:00  \_ /apache2/bin/httpd -k start
nobody   22664  0.0  0.1   6880  3540  ?   S    22:24   0:00  \_ /apache2/bin/httpd -k start
         其中,%CPU表示進程佔用的CPU百分比,%MEM表示進程佔用內存的百分比,VSZ表示進程虛擬大小,RSS表示進程的實際內存(駐留集)大小(單位是頁)。STAT表示進程的狀態,進程的狀態有不少種:用「R」表示正在運行中的進程,用「S」表示處於休眠狀態的進程,用「Z」表示僵死進程,用「<」表示優先級高的進程,用「N」表示優先級較低的進程,用「s」表示父進程,用「+」表示位於後臺的進程。START表示啓動進程的時間。
         這個例子將進程之間的關係用樹形結構形象的表示出來,能夠很清楚的看到,第一個進程爲父進程,而其它進程均爲子進程。同時從這個輸出還能夠看到每一個進程佔用CPU、內存的百分比,還有進程所處的狀態等等。sql

2.2 利用pstree監控系統進程
 pstree命令以樹形結構顯示程序和進程之間的關係,使用格式以下:
 pstree [-acnpu] [<PID>/<user>]
 選項含義以下:
 -a  顯示啓動每一個進程對應的完整指令,包含啓動進程的路徑、參數等等。
 -c  不使用精簡法顯示進程信息,即顯示的進程中包含子進程和父進程。
 -n  根據進程PID號來排序輸出,默認是以程序名稱排序輸出的。
 -p  顯示進程的PID。
 -u  顯示進程對應的用戶名稱。
 PID:即進程對應的PID號,或者叫進程識別號。
 user:系統用戶名。
         pstree清楚的顯示了程序和進程之間的關係,若是不指定進程的PID號,或者不指定用戶名稱,則將以init進程爲根進程,顯示系統的全部程序和進程信息,若指定用戶或PID,則將以用戶或PID爲根進程,顯示用戶或PID對應的全部程序和進程。
舉例以下:
若是想知道某個用戶下都啓動了哪些進程的話,pstree指令能夠很容易實現,下面顯示mysql用戶下對應的進程信息,執行以下命令:
[root@localhost ~]# pstree mysql   
mysqld---6*[{mysqld}]
該輸出顯示了mysql用戶下對應的進程爲mysqld,而且mysqld進程擁有5個子進程(5個子進程加一個父進程,共6個進程)。
爲了更詳細的瞭解每一個進程的信息,例如每一個子進程和父進程對應的PID,執行以下命令:
[root@localhost ~]# pstree -c -p mysql
mysqld(18785)-+-{mysqld}(18787)
              |-{mysqld}(18788)
              |-{mysqld}(18789)
              |-{mysqld}(18790)
              |-{mysqld}(18791)
              `-{mysqld}(29625)
經過「-p、-c」參數,清楚的顯示了父進程和子進程,以及它們各類的PID。
若是知道進程對應的PID,想獲得進程是由哪一個用戶啓動的,能夠執行以下命令:
[root@localhost ~]# pstree -u 26037
httpd---10*[httpd(nobody)]
從上面可知,httpd進程是由nobody用戶啓動的。
若是要查看httpd父進程和每一個子進程分別對應的PID,能夠執行以下命令組合:
[root@localhost ~]# pstree -u -p 26037
httpd(26037)-+-httpd(24562,nobody)
             |-httpd(24563,nobody)
             |-httpd(24566,nobody)
             |-httpd(24567,nobody)
             |-httpd(24631,nobody)
             |-httpd(24648,nobody)
             |-httpd(24650,nobody)
             |-httpd(24654,nobody)
             |-httpd(26156,nobody)
             `-httpd(29014,nobody)
若是要獲得啓動httpd進程的程序路徑、參數組合,執行以下命令:
[root@localhost ~]# pstree -a -u -p 26037
httpd,26037 -k start
  |-httpd,24563,nobody -k start
  |-httpd,24566,nobody -k start
  |-httpd,24567,nobody -k start
  |-httpd,24631,nobody -k start
  |-httpd,24648,nobody -k start
  |-httpd,24650,nobody -k start
  |-httpd,24654,nobody -k start
  |-httpd,26156,nobody -k start
  `-httpd,29014,nobody -k startshell

2.3  利用top監控系統進程
         top命令是監控系統進程必不可少的工具,與ps命令相比,top命令動態、實時的顯示進程狀態,而ps只能顯示進程某一時刻的信息,同時,top命令提供了一個交互界面,用戶能夠根據須要,人性化的定製本身的輸出,更清楚的瞭解進程的實時狀態。
          關於top指令的用法,在第四章已經有了詳細的介紹,這裏經過幾個例子,闡述一下top命令在系統進程監控中的做用和優勢。
下面這個例子是某系統在某時刻執行top命令後的輸出:
[root@webserver ~]# top
Tasks: 126 total,   1 running, 123 sleeping,   1 stopped,   1 zombie
Cpu(s):  0.8% us,  0.1% sy,  0.0% ni, 99.0% id,  0.0% wa,  0.0% hi,  0.0% si
Mem:   8306544k total,  8200452k used,   106092k free,   234340k buffers
Swap:  8385888k total,      160k used,  8385728k free,  7348560k cachedapache

PID    USER     PR  NI  VIRT   RES    SHR   S  %CPU   %MEM     TIME+    COMMAND                                                                
21115  root     23   0 1236m  360m   2384   S    6     4.4     382:24.14  java                                                                   
30295  root     16   0  3552   984    760   R    1     0.0     0:00.09    top                                                                    
30118 nobody    15   0  6904  3132   1676   S    0     0.0     0:00.47    httpd 
30250 nobody    15   0  6900  3088   1660   S    0     0.0     0:00.06    httpd                                                                  
  1    root     16   0  1780   552    472   S    0     0.0     0:01.25     init     
         從top命令的輸出可知,此係統有java和httpd兩個用戶進程在運行。
進程PID爲21115的java進程由root用戶啓動,優先級(PR)爲23,佔用的虛擬內存總量(VIRT)爲1236M,未被換出的物理內存(RES)爲360M,共享內存(SHR)爲2384 kb。經過這幾個選項能夠了解java進程對內存的使用量,有助於系統管理員對系統虛擬內存使用情況的掌控。
         此刻java進程處於休眠狀態(S),從上次更新到如今java佔用cpu時間(%CPU)爲6%,佔用物理內存(%MEM)爲4.4%,從進程啓動到如今java佔用cpu總時間(TIME+)爲「382:24.14」,單位是1/100秒。經過了解這些信息,可使系統管理員掌握java進程對系統CPU、物理內存的使用情況。
兩個httpd進程由nobody用戶啓動,優先級都爲15,同時都處於休眠狀態。
除去這兩個進程,還有top進程,也就是咱們執行top命令產生的進程,從進程狀態項可知,此進程處於運行狀態,另外一個是init進程,即全部系統進程的父進程,對應的PID爲1。
         固然top的輸出還有不少進程信息,這裏僅僅拿出前幾個進程進行重點講解,理解其它進程的含義基本與這些相同。windows

2.4 利用lsof監控系統進程與程序
          lsof全名list opened files,也就是列舉系統中已經被打開的文件,經過lsof,咱們就能夠根據文件找到對應的進程信息,也能夠根據進程信息找到進程打開的文件。
lsof指令功能強大,這裏介紹「-c,-g,-p,-i」這四個最經常使用參數的使用。更詳細的介紹請參看man lsof。
 lsof filename:顯示使用filename文件的進程。
若是想知道某個特定的文件由哪一個進程在使用,能夠經過「lsof 文件名」方式獲得,例如:
[root@localhost ~]# lsof /var/log/messages
COMMAND  PID USER   FD   TYPE DEVICE  SIZE  NODE NAME
syslogd 2027 root    1w   REG    8,6 43167 31916 /var/log/messages
從這個輸出可知,/var/log/messages文件是由syslogd進程在使用。
 lsof -c abc :顯示abc進程如今打開的文件,例如:
 [root@localhost ~]# lsof -c nfs  
COMMAND  PID USER   FD      TYPE DEVICE SIZE NODE NAME
nfsd4   2761 root  cwd       DIR    8,3 4096    2  /
nfsd4   2761 root  rtd       DIR    8,3 4096    2  /
nfsd4   2761 root  txt    unknown                  /proc/2761/exe
nfsd    2762 root  cwd       DIR    8,3 4096    2  /
nfsd    2762 root  rtd       DIR    8,3 4096    2  /
nfsd    2762 root  txt   unknown                   /proc/2762/exe
nfsd    2763 root  cwd       DIR    8,3 4096    2  /
nfsd    2763 root  rtd       DIR    8,3 4096    2  /
nfsd    2763 root  txt   unknown                   /proc/2763/exe
    上例顯示了nfs進程打開的文件信息,FD列表示文件描述符,TYPE列顯示文件的類型,SIZE列顯示文件的大小,NODE列顯示本地文件的node碼,NAME列顯示文件的全路徑或掛載點。
 lsof -g gid:顯示指定的進程組打開的文件狀況,例如:
[root@localhost ~]# lsof -g 3626
COMMAND   PID PGID  USER   FD   TYPE     DEVICE    SIZE    NODE NAME
sendmail 3626 3626 smmsp  cwd    DIR        8,8 4853760   32714 /var/spool/clientmqueue
sendmail 3626 3626 smmsp  rtd    DIR       8,10    4096       2 /
sendmail 3626 3626 smmsp  txt    REG        8,9  732356 1152124 /usr/sbin/sendmail.sendmail
sendmail 3626 3626 smmsp  mem    REG       8,10  106397 1158794 /lib/ld-2.3.4.so
sendmail 3626 3626 smmsp  mem    REG       8,10   95148 1175044 /lib/libnsl-2.3.4.so
.............省略...............
sendmail 3626 3626 smmsp    3u  unix 0xf41e5bc0            9592 socket
sendmail 3626 3626 smmsp    4wW  REG        8,8      50  523293 /var/run/sm-client.pid
其中,PGID列表示進程組的ID編號。
上面輸出,顯示了sendmail程序當前打開的全部文件、設備、庫及套接字等。
 lsof -p PID:PID是進程號,經過進程號顯示程序打開的全部文件及相關進程,例如,想知道init進程打開了哪些文件的話,能夠執行「lsof -p  1」命令,輸出結果以下: 
[root@localhost ~]# lsof -p  1   
COMMAND PID USER   FD   TYPE DEVICE    SIZE    NODE NAME
init      1 root  cwd    DIR   8,10    4096       2 /
init      1 root  rtd    DIR   8,10    4096       2 /
init      1 root  txt    REG   8,10   32684  897823 /sbin/init
init      1 root  mem    REG   8,10   56320 2175328 /lib/libselinux.so.1
init      1 root  mem    REG   8,10  106397 1158794 /lib/ld-2.3.4.so
init      1 root  mem    REG   8,10 1454462 1161560 /lib/tls/libc-2.3.4.so
init      1 root  mem    REG   8,10   53736 1158819 /lib/libsepol.so.1
init      1 root   10u  FIFO   0,13             966 /dev/initctl數組

 lsof -i 經過監聽指定的協議、端口、主機等信息,顯示符合條件的進程信息。
使用語法爲:
    lsof -i [46] [protocol][@hostname][:service|port]
 46:4表明IPv4,6表明IPv6。
 protocol:傳輸協議,能夠是TCP或UDP。
 hostname:主機名稱或者IP地址。
 service:進程的服務名,例如nfs、ssh、ftp等。
 port:系統中服務對應的端口號。例如http服務默認對應80,ssh服務默認對應22等等。
例如:
顯示系統中tcp協議對應的25端口進程信息:
[root@localhost ~]# lsof -i tcp:25
COMMAND   PID USER    FD   TYPE  DEVICE SIZE   NODE         NAME
sendmail 2252 root    4u   IPv4   5874         TCP   localhost:smtp (LISTEN)
顯示系統中80端口對應的進程信息:
[root@localhost ~]# lsof -i :80
COMMAND   PID   USER      FD   TYPE  DEVICE SIZE   NODE     NAME
httpd   16474   nobody    3u   IPv6  7316069       TCP   *:http (LISTEN)
httpd   16475   nobody    3u   IPv6  7316069       TCP   *:http (LISTEN)
httpd   16578   nobody    3u   IPv6  7316069       TCP   *:http (LISTEN)
 顯示本機udp協議對應的53端口開啓的進程信息:
[root@localhost ~]# lsof -i udp@127.0.0.1:53
COMMAND   PID  USER     FD   TYPE   DEVICE  SIZE NODE      NAME
named    21322 named   20u   IPv4   9130640      UDP   localhost:domain 
   經過lsof命令可以清楚的瞭解進程和文件以及程序之間的對應關係,熟練掌握lsof的使用,對linux的進程管理有很大幫助。

相關文章
相關標籤/搜索