系統進程與線程

系統進程與線程

1.進程php

進程一般被定義爲程序執行時的一個實例,是任何多道程序設計的操做系統中的基本概念。在linux源碼中,進程一般被稱爲"任務"。每一個進程都在cpu虛擬內存中分配地址空間中運行,每一個進程的地址空間是徹底獨立的,由於不一樣進程之間不會意識到其它進程的存在。兩個進程若是想相互通訊,則必需要藉助內核來實現。python

linux爲多任務系統,表面上同時在運行多個進程,可是實際系統中同時只會遇到不超過cpu核心的進程,也就是一個cpu核心中只會運行一個進程。mysql

由於不可能存在讓某一個進程直接運行完成,因此內核將cpu的運行時間切割成不少時間片斷,經過內核來進行調度,依次優先度對各個進程進行執行與切換,這個切換也就是系統中的cpu上下文切換(context switch),能夠經過top命令來查看linux

2.線程nginx

能夠簡單的理解爲線程是cpu調試的最少單元。更爲簡單的能夠理解成線程爲同一個程序裏面的多個函數同時運行,進程是線程集。git

3.線程與進程的淵源redis

在傳統進程模式中,進程的內涵能夠分爲兩個方面:sql

a.調試、執行的基本單位

b.資源全部權

由於是兩個獨立的功能,因此現代操做系統就將其進行分裂centos

執行與調試的基本單位:thread(線程)

資源全部權:process(進程)

在這種模式之下,內核調試的基本單位是線程而非進程,進程只須要負責管理資源,這些資源則由同一進程下的線程共享。ruby

線程出現以後,帶來了如下便利:

a.建立、終止、切換thread的開銷要比process小不少

b.因爲地址空間共享,因此線程通訊與進程通訊高效不少

不過在linux中,內核使用task_struct這一數據結構表明傳統意義上的進程、線程,而不是爲兩者分別定義數據結構(如大多數操做系統)

在linux中,不管進程仍是線程,根本上都是經過clone一個已經存在的task(進程/線程)來實現的,二者的差異就在於clone時flags的傳遞,當共享地址空間設置時(clone_VM位),建立線程,當沒設置時則建立進程。

在linus一封對線程與進程解釋的信件中,有一段話頗有意思

There is NO reason to think that "threads" and "processes" are separateentities. That's how it's traditionally done, but I personally think it's amajor mistake to think that way. The only reason to think that way ishistorical baggage. 

Both threads and processes are really just one thing: a "context of execution". Trying to artificially distinguish different cases is justself-limiting. 

A "context of execution", hereby called COE, is just the conglomerate of all the state of that COE. That state includes things like CPU state (registers etc), MMU state (page mappings), permission state (uid, gid) and various "communication states" (open files, signal handlers etc).

Traditionally, the difference between a "thread" and a "process" has beenmainly that a threads has CPU state (+ possibly some other minimal state),while all the other context comes from the process. However, that's just_one_ way of dividing up the total state of the COE, and there is nothingthat says that it's the right way to do it. Limiting yourself to that kind ofimage is just plain stupid. 

The way Linux thinks about this (and the way I want things to work) is thatthere _is_ no such thing as a "process" or a "thread". There is only thetotality of the COE (called "task" by Linux). Different COE's can share partsof their context with each other, and one _subset_ of that sharing is thetraditional "thread"/"process" setup, but that should really be seen as ONLYa subset (it's an important subset, but that importance comes not fromdesign, but from standards: we obviusly want to run standards-conformingthreads programs on top of Linux too). In short: do NOT design around the thread/process way of thinking. The kernel should be designed around the COE way of thinking, and then the pthreads _library_ can export the limited pthreads interface to users who want to use that way of looking at COE's.

進程狀態

由於程序並非一次性運行,由於其被擱置等有不一樣的狀態。全部狀態有以下幾種:

運行態:running(R),進程正在cpu上運行中。

就緒態:ready(R),進程處於準備運行狀態,它被放置在一個運行隊列中,等待系統分配 CPU 資源給它,只有在該狀態的進程纔可能在cpu上運行

睡眠態:其中包括兩種狀態

可中斷:interruptable(S),即進程在休眠中,因爲在等待某個事件的完成(或等待某個條件的造成或等待某個信號等),通常狀況下,進程列表中絕大多數進程都處於該狀態。

    不可中斷:uninterruptable(D),不可中斷指的並非CPU不響應外部硬件的中斷,而是指進程不響應異步信號,沒法用kill命令殺死,進程必須等待直到有中斷髮生。處於這個狀態的進程一般須要等待某個資源,並且在等待過程當中進程會忽略任何信號。

中止態:stopped(T),暫停於內存中,但不會被調試,除非手動啓動之:stopped

僵死態:zombie(Z),也就是處於僵死狀態。若是該子進程的父進程沒有收到SIGCHLD信號,故未調用wait(如wait四、waitid)處理函數等待子進程結束,又沒有顯示忽略該信號,該子進程就一直保持僵死狀態。只要父進程不退出,這個僵死的子進程就一直存在。

PID

系統中每一個進程都由一個正整數來進行惟一標識描述,這個值就是叫pid。pid值是系統隨機分配的,當進程結束以後,其pid也會回收。

當一個程序啓動時,會向內核發送pid申請請求,若是系統發現其pid存在,則斷定其爲啓動狀態,則返回一個啓動錯誤的信息,從而保證一個程序屢次啓動。

固然在linux中子進程並非單獨生成的,其都是依據其父進程來進行fork,由於進程以前會有資源共享,因此直接對父進程進行fork,在2000以後,linux引入新的system call,也就是clone(),經過clone來進行子進程的生成。

在centos6中的,全部的進程都是基於init進程來進行fork。使用pstree能夠查看,init的id值就是1

[root@iZ2ze4pxwbsbyvwn8l6qxbZ ~]# pstree
init─┬─AliYunDun───13*[{AliYunDun}]
     ├─AliYunDunUpdate───3*[{AliYunDunUpdat}]
     ├─aliyun-service
     ├─atd
     ├─auditd───{auditd}
     ├─bundle─┬─3*[bundle───{bundle}]
     │        └─2*[{bundle}]
     ├─crond
     ├─freeswitch───30*[{freeswitch}]
     ├─httpd───8*[httpd]
     ├─master─┬─pickup
     │        └─qmgr
     ├─6*[mingetty]
     ├─mysqld_safe───mysqld───20*[{mysqld}]
     ├─ntpd
     ├─rsyslogd───3*[{rsyslogd}]
     ├─runsvdir─┬─runsv─┬─redis-server───2*[{redis-server}]
     │          │       └─svlogd
     如下略

而在centos7中,由於已經使用systemd取代了init

[root@iZ25e35hsefZ ~]# pstree
systemd─┬─AliYunDun───14*[{AliYunDun}]
        ├─AliYunDunUpdate───3*[{AliYunDunUpdate}]
        ├─agetty
        ├─aliyun-service
        ├─crond
        ├─dbus-daemon
        ├─iprdump
        ├─iprinit
        ├─iprupdate
        ├─lvmetad
        ├─mysqld_safe───mysqld───27*[{mysqld}]
        ├─nginx───4*[nginx]
        ├─nscd───7*[{nscd}]
        ├─ntpd
        ├─php-fpm───20*[php-fpm]
        ├─polkitd───5*[{polkitd}]
        ├─qpidd───5*[{qpidd}]
        ├─redis-server───2*[{redis-server}]
        ├─rsyslogd───2*[{rsyslogd}]
        ├─sshd─┬─2*[sshd───bash]
        │      ├─sshd───sshd───bash───mysql
        │      └─sshd───bash───pstree
        ├─systemd-journal
        ├─systemd-logind
        ├─systemd-udevd
        ├─vsftpd
        └─zabbix_agentd───5*[zabbix_agentd]

PPID

每一個進程除了有pid值,還會有ppid值,也就是其父進程的id值,能夠依據ps命令來查看ppid值

[root@iZ25b31bdp0Z ~]# ps ax -o user,pid,ppid,stat,command
USER       PID  PPID STAT COMMAND
root         1     0 Ss   /usr/lib/systemd/systemd --switched-root --system --deserialize 22
root       939     1 Ss+  /sbin/agetty --noclear tty1 linux
zabbix     952     1 S    /usr/sbin/zabbix_agentd -c /etc/zabbix/zabbix_agentd.conf
zabbix     960   952 S    /usr/sbin/zabbix_agentd: collector [idle 1 sec]
zabbix     961   952 S    /usr/sbin/zabbix_agentd: listener #1 [waiting for connection]
zabbix     962   952 S    /usr/sbin/zabbix_agentd: listener #2 [waiting for connection]
zabbix     963   952 S    /usr/sbin/zabbix_agentd: listener #3 [waiting for connection]
zabbix     964   952 S    /usr/sbin/zabbix_agentd: active checks #1 [idle 1 sec]
mysql     1013     1 Ss   /bin/sh /usr/bin/mysqld_safe --basedir=/usr
named     1194     1 Ssl  /usr/sbin/named -u named
如下略

進程管理查看工具

1.top

top命令是centos自帶的命令,能夠在其中查看cpu,mem的使用量及程序各個對的資源的佔用量

top - 14:18:59 up 15 days, 21:42,  6 users,  load average: 0.02, 0.20, 0.22
Tasks: 201 total,   2 running, 199 sleeping,   0 stopped,   0 zombie
%Cpu(s):  0.3 us,  0.7 sy,  0.0 ni, 98.9 id,  0.1 wa,  0.0 hi,  0.0 si,  0.0 st
KiB Mem:   3620188 total,  2350684 used,  1269504 free,   219640 buffers
KiB Swap:        0 total,        0 used,        0 free.   117888 cached Mem

  PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND                                                                                                       
 1473 mysql     20   0 3078344 437568   3456 S   0.0 12.1  29:10.51 mysqld                                                                                                        
32658 git       20   0 1029176 400692   5812 S   0.7 11.1   6:15.10 .ruby.bin                                                                                                     
 9923 nobody    20   0 2342904 116044  14608 S   0.0  3.2   8:00.54 httpd                                                                                                         
 9767 nobody    20   0 2342900 115468  13132 S   0.0  3.2   5:59.61 httpd                                                                                                         
 9770 nobody    20   0 2342900 113244  14828 S   0.0  3.1   6:53.30 httpd                                                                                                         
 9768 nobody    20   0 2342900 113208  14068 S   0.0  3.1   6:19.60 httpd                                                                                                         
 9766 nobody    20   0  731908  40760   2352 S   0.0  1.1   6:55.98 mysqld                                                                                                        
32378 root      20   0  549580  36000  27588 S   0.0  1.0   0:02.09 httpd.bin                                                                                                     
 1194 named     20   0  397144  28948   1820 S   0.0  0.8   0:29.86 named                                                                                                         
32665 postgres  20   0  297784  20508   9212 S   0.0  0.6   0:20.15 postgres.bin                                                                                                  
30570 rd        20   0  649288  20160   4440 S   0.0  0.6   0:00.13 php-fpm                                                                                                       
30084 rd        20   0  648524  19716   4556 S   0.0  0.5   0:00.21 php-fpm                                                                                                       
28940 rd        20   0  647368  19028   5068 S   0.0  0.5   0:00.41 php-fpm                                                                                                       
28865 rd        20   0  646820  18576   5076 S   0.0  0.5   0:01.09 php-fpm                                                                                                       
28533 rd        20   0  646788  18484   5068 S   0.0  0.5   0:01.07 php-fpm

進入top以後,比較多的有如下幾個變量

單按M:程序使用內存量從高到低排列
單按C:程度使用cpu量從高到低
單按1:顯示每顆cpu運行狀態

相關變量解釋爲

PID:進程 ID
USER:運行進程的用戶身份
PRI:進程的優先級
NI: 進程的 NICE 值,這個值從 -20 ~ 19,數值越小優先級越高
VIRT:進程的虛擬內存使用量
RES:進程的實際物理內存使用量
SHR:進程的內存中使用的共享內存映射的區域大小
S:進程的狀態
CPU%:進程的 CPU 使用率
MEM%:進程的內存使用率
TIME+:進程佔用 CPU 的累積時長
Command:進程的啓動指令

2.htop

htop是epel源中的一個程序,默認不會安裝,其與top界面很相似,基本同樣,只是在top的基礎命令進行了相關的整合。

3.glances

glances與htop同樣,也只存在於epel源中,系統並不會默認安裝。glances爲一款python開發的工具,除了top顯示進程的相關信息及資源消耗以外,其還能顯示磁盤、網絡的情況

界面中相關的快捷鍵使用以下:

h:顯示幫助信息
q:離開程序退出
c:按照 CPU 實時負載對系統進程進行排序
m:按照內存使用情況對系統進程排序
i:按照 I/O 使用情況對系統進程排序
p:按照進程名稱排序
d:顯示磁盤讀寫情況 
w:刪除日誌文件
l:顯示日誌
s:顯示傳感器信息
f:顯示系統信息
1:輪流顯示每一個 CPU 內核的使用狀況(次選項僅僅使用在多核 CPU 系統)
u:顯示網絡接口的累積流量
相關文章
相關標籤/搜索