linux 進程管理和記憶體分配
1、進程相關概念
進程:正在運行中的程式
內核功用:進程管理、文件系統、網路功能、記憶體管理、驅動程式、安全功能等
Process:運行中的程式的一個副本,是被載入記憶體的一個指令集合
進程 ID(Process ID,PID)號碼被用來標記各個進程
通常從執行進程的用戶來繼承,存在生命周期
task struct 任務結構表:Linux 內核存儲進程資訊的數據結構格式
task list 任務列表:多個任務的 task struct 組成的鏈表
進程創建:
都由其父進程創建,父好關係,CoW(寫時複製,不發生改變時父子都指向同一文件;發生改變時,則複製)
init:第一個進程(centos6:init,centos7:systemd)
守護進程:隨著電腦的開啟、關閉而隨之開啟、關閉。
2、進程,執行緒和協程:
註:一個進程里至少有一個執行緒;執行緒之間由作業系統進行調度,包括進程中使用的資源也由作業系統進行調度;協程相當於執行緒中的語句塊,由執行緒控制。
3、Page Frame:頁框,用存儲頁面數據,存儲 Page,每個進程要使用的分配空間
虛擬記憶體(線性記憶體):進程運行的時候以為自己擁有了全部的記憶體空間
物理地址空間和線性地址空間:
MMU:負責轉換線性和物理地址(虛擬記憶體和物理記憶體)
TLB:翻譯後備緩衝器,用於保存虛擬地址和物理地址映射關係的快取
LRU:近期最少使用演算法,釋放記憶體
4、用戶空間和內核空間:
5、進程之間基本狀態和轉換:
創建狀態:進程在創建時需要申請一個空白 PCB(進程式控制制塊),向其中填寫控制和管理進程的資訊,完成資源分配。如果創建工作無法完成,比如資源無法滿足,就無法被調度運行,把此時進程所處狀態稱為創建狀態。
就緒狀態:進程已準備好,已分配到所需資源,只要分配到 CPU 就能夠立即運行。
執行狀態:進程處於就緒狀態被調度後,進程進入執行狀態。
阻塞狀態:正在執行的進程由於某些事件(I/O 請求,申請快取區失敗)而暫時無法運行,進程受到阻塞,在滿足請求時進入就緒狀態等待系統調用。
終止狀態:進程結束,或出現錯誤,或被系統終止,進入終止狀態,無法再執行。
狀態之間轉換六種情況:
運行 → 就緒:1,主要是進程佔用 CPU 的時間過長,而系統分配給該進程佔用 CPU 的時間是有限的;2,在採用搶先式優先順序調度演算法的系統中,當有更高優先順序的進程要運行時,該進程就被迫讓出 CPU,該進程便由執行狀態轉變為就緒狀態。
就緒 → 運行:運行的進程的時間片用完,調度就轉到就緒隊列中選擇合適的進程分配 CPU。
運行 → 阻塞:正在執行的進程因發生某等待事件而無法執行,則進程由執行狀態變為阻塞狀態如發生了 I/O 請求。
阻塞 → 就緒:進程所等待的事件已經發生,就進入就緒隊列。
以下兩種狀態是不可能發生的:
阻塞 → 運行:即使給阻塞進程分配 CPU,也無法執行,作業系統在進行調度時,不會從阻塞隊列進行挑選,而是從就緒隊列中選取。
就緒 → 阻塞:就緒態根本就沒有執行,談不上進入阻塞態。
6、IPC 進程間通訊:
同一主機:
pipe 管道,一個寫入管道文件,一個讀(單向)
socket 套接字文件,進程間交換數據(雙工工作方式)
signal 訊號
shm shared memory,共享記憶體
semaphore 訊號量,一種計數器,分配資源
不同主機:
socket ip 和埠號
RPC 遠程過程調用
MQ 消息隊列,如:Kafka , RabbitMQ,ActiveMQ
7、進程優先順序
實時進程(realtime),基於 FIFO 先進先出或 RR 輪詢
非實時進程:nice 按時間片分配進程
取 139 個隊列,將相同優先順序的放在一個隊列中,運行一個時間片後從運行隊列轉至過期隊列。輪迴運行隊列和過期隊列互調,再運行。
進程優先順序:
系統優先順序:數字越小,優先順序越高
0-139:各有 140 個運行隊列和過期隊列
實時優先順序:99-0 值最大優先順序最高
nice 值:-20 到 19,對應系統優先順序 100-139
Big 0:時間複雜度,用時和規模的關係
0(1),O(logn),O(n)線性,O(n^2)拋物線,O(2^n)
8、進程狀態:
Linux 內核:搶佔式多任務,按時間片分配任務
進程類型:
守護進程:daemon,在系統引|導過程中啟動的進程,和終端無關進程
前台進程:跟終端相關,通過終端啟動的進程,用戶執行命令等
注意:兩者可相互轉化
進程狀態:
運行態:running
就緒態:ready
睡眠態:
可中斷:interruptable
不可中斷:uninterruptable
停止態:stopped,暫停於記憶體,但不會被調度,除非手動啟動
僵死態:zombie,結束進程,父進程結束前,子進程不關閉
9、進程工具
9.1 系統管理工具:
進程的分類:
CPU-Bound:CPU 密集型,非交互
編譯安裝、大量計算等
IO-Bound:IO 密集型,交互
拷貝大文件等 DMA:直接記憶體訪問
Linux 系統狀態的查看及管理工具:
pstree,ps,pidof,pgrep,top,htop,glance,pmap,vmstat,dstat,kill,pkill,job,bg,fg,nohup
Linux 系統各進程的相關資訊均保存在 /proc/PID 目錄下的各文件中
9.2 進程管理工具 PS 詳解:
ps [OPTION]... 支援三種選項: UNIX 選項 如-A -e BSD 選項 如 a GNU 選項 如--help
選項:默認顯示當前終端中的進程 a 選項包括所有終端中的進程 x 選項包括不鏈接終端的進程 u 選項顯示進程所有者的資訊(有效用戶) f 選項顯示進程樹,相當於--forest k|--sort 屬性對屬性排序,屬性前加-表示倒序 o 屬性...選項顯示訂製的資訊 pid、cmd、%cpu、%mem L 顯示支援的屬性列
ps axo pid,%cpu,%mem,tty k %cpu -C cmdlist 指定命令,多個命令用,分隔,ps -C dd -L 顯示執行緒 -e 顯示所有進程,相當於-A -f 顯示完整格式程式資訊 -F 顯示更完整格式的進程資訊 -H 以進程層級格式顯示進程相關資訊 -u userlist 指定有效的用戶 ID 或名稱 -U userlist 指定真正的用戶 ID 或名稱 -g gid 或 groupname 指定有效的 gid 或組名稱 -G gid 或 groupname 指定真正的 gid 或組名稱 -p pid 顯示指 pid 的進程 --ppid pid 顯示屬於 pid 的子進程 -M 顯示 SELinux 資訊,相當於 Z
PS 輸出屬性: VSZ:Virtual memory SiZe,虛擬記憶體集,線性記憶體 RSS:ReSident Size,常駐記憶體集 STAT:進程狀態 R:running S:interruptable sleeping,可中斷的休眠 D:uninterruptable sleeping,不可中斷的休眠 T:stopped,停止態 Z:zombie,殭屍態 +:前台進程 |:多執行緒進程 L:記憶體分頁並帶鎖 N:低優先順序進程 <:高優先順序進程 s:session leader,會話 (子進程)發起者
ps 優先順序選項和常用組合: ni:nice 值 pri:priority 優先順序,和系統優先順序相反 psr:processor CPU 編號,CPU(一級二級,三級[共享]快取) 更換 CPU 快取失效,解決:綁定進程和 CPU taskset -p [進程 ID],查看,命令顯示和 CPU 核數不一樣[二進位] tackset -cp 1 [進程 ID],綁定在 1 號 CPU 上 0,4 0-4 等 pidof dd,查看 dd 命令的進程編號 rtprio:實時優先順序 # 示例: ps axo pid,cmd,psr,ni,pri,rtprio # 常用組合: aux -ef -eFH -eo pid,tid,class,rtprio,ni,pripsr,pcpu,stat,comm axo stat,euid,ruid,tty,tpgid,sess,pgrp,ppid,pid,pcpu,comm nice -n 10 ping 192.168.129.142 # 以指定優先順序運行該命令 renice # 更改優先順序
PS示例:
# 列出有效組名稱(或會話)所擁有的所有進程 ps -fg mysql ps -fg 27
# 顯示指定的進程 ID 對應的進程 ps -fp 1234
# 以父進程 ID 來顯示其下所有的進程,如顯示父進程為 1234 的所有進程 ps -f –ppid 1234
# 顯示指定 PID 的多個進程 ps -fp 1234,1236,1264
# 要按 tty 顯示所屬進程 ps -ft pts/0
# 自定義格式顯示文件系統組,ni 值開始時間和進程的時間 ps -p 1234 -o pid,ppid,fgroup,ni,lstart,etime
# 使用其 PID 查找進程名稱 ps -p 1234 -o comm=
# 要使用其名稱選擇特定進程,顯示其所有子進程 ps -C sshd,bash
# 查找指定進程名所有的所屬 PID,在編寫需要從 std 輸出或文件讀取 PID 的腳本時這個參數很有用 ps -C httpd,sshd -o pid=
# 檢查一個進程的執行時間 ps -eo comm,etime,user | grep nginx
# 查找佔用最多記憶體和 CPU 的進程 ps -eo pid,ppid,cmd,%mem,%cpu --sort=-%mem | head ps -eo pid,ppid,cmd,%mem,%cpu --sort=-%cpu | head
# 顯示安全資訊 ps-eM ps --context
# 使用以下命令以用戶定義的格式顯示安全資訊 ps -eo euser,ruser,suser,fuser,f,comm,label
# 使用 watch 實用程式執行重複的輸出以實現對就程進行實時的監視,如下面的命令顯示每秒鐘的監視 watch -n 1 'ps -eo pid,ppid,cmd,%mem,%cpu --sort=-%mem| head'
搜素進程:
最靈活:ps 選項 | 其它命令 按預定義的模式:pgrep pgrep [options] pattern -u uid: effective user,生效者 -U uid: realuser,真正發起運行命令者 -t terminal:與指定終端相關的進程 pgrep -t pts/1 -l:顯示進程名 -a:顯示完整格式的進程名 -P pid:顯示指定進程的子進程
按確切的程式名稱查詢進程 ID: /sbin/pidof pidof bash
9.3 top 詳解
top:有許多內置命令 排序: P:以佔據的 CPU 百分比,%CPU M:佔據記憶體百分比,%MEM T:累積佔據 CPU 時長,TIME+
首部資訊顯示: uptime 資訊: |命令 tasks 及 cpu 資訊: t 命令 cpu 分別顯示: 1 (數字) memory 資訊: m 命令 退出命令: q 修改刷新時間間隔: s 終止指定進程: k 保存文件: W
欄位資訊簡介 us:用戶空間 sy:內核空間 ni:調整 nice 時間 id:空閑 wa:等待 IO 時間 hi:硬中斷 si:軟中斷(模式切換) st:虛擬機偷走的時間
選項: -d # 指定刷新時間間隔,默認為 3 秒 -b 全部顯示所有進程 -n # 刷新多少次後退出 -H 執行緒模式,示例:top -H -p `pidof mysqld`
9.4 htop 詳解
htop 命令:EPEL 源 選項: -d #:指定延遲時間; -u UserName:僅顯示指定用戶的進程 -s COLUME:以指定欄位進行排序
子命令: s:跟蹤選定進程的系統調用 |:顯示選定進程打開的文件列表 a:將選定的進程綁定至某指定 CPU 核心 t:顯示進程樹
10、記憶體管理工具
10.1 free 命令詳解
記憶體空間使用狀態: free [OPTION] -b 以位元組為單位 -m 以 MB 為單位 -g 以 GB 為單位 -h 易讀格式 -0 不顯示-/+ buffers/cache 行 -t 顯示 RAM + swap 的總和 -s n 刷新間隔為 n 秒 -c n 刷新 n 次後即退出 cat /proc/sys/vm/drop_caches # 快取為 0,重定向一個 3 進去清理快取
10.2 記憶體工具 vmstat
vmstat 命令:虛擬記憶體資訊 vmstat [options] [delay [count]] vmstat 2 5 # 2 秒執行一次,執行 5 次退出
procs: r:可運行(正運行或等待運行)進程的個數,和核心數有關 b:處於不可中斷睡眠態的進程個數(被阻塞的隊列的長度) memory: swpd:交換記憶體的使用總量 free:空閑物理記憶體總量 buffer:用於 buffer 的記憶體總量 cache:用於 cache 的記憶體總量 swap: si:從磁碟交換進記憶體的數據速率(kb/s) so:從記憶體交換至磁碟的數據速率(kb/s) io: bi:從塊設備讀入數據到系統的速率(kb/s) bo:保存數據至塊設備的速率 system: in:interrupts 中斷速率,包括時鐘 cs:context switch 進程切換速率 cpu: us:Time spent running non-kernel code sy:Time spent running kernel code id:Time spent idle. Linux 2.5.41 前,包括 IO-wait time. wa:Time spent waiting for IO.2.5.41 前 ,包括 in idle. st:Time stolen from a virtual machine. 2.6.11 前, unknown.
選項: -s:顯示記憶體的統計數據
11、iostat 統計CPU和設備IO資訊
例: iostat 1 10
12、iftop 顯示頻寬使用情況,epel源
例:
iftop -n -i eth1
13、pmap 命令:進程對應的記憶體映射
pmap [options] pid [..] -X:顯示詳細格式的資訊 例: pmap1
14、系統監控工具
glances 命令: EPEL 源
glances [-bdehmnrsvyz1] [-B bind] [-c server] [-C conffile] [-p port] [-P password] [--password] [-t refresh] [-f file] [-o output] 內建命令: a – 對進程自動排序
c – 按 CPU 百分比對進程排序
m – 按記憶體百分比對進程排序
p – 按進程名字母順序對進程排序
i – 按讀寫頻率(I/O)對進程排序
d – 顯示/隱藏磁碟 I/O 統計資訊
f – 顯示/隱藏文件系統統計資訊
n – 顯示/隱藏網路介面統計資訊
s – 顯示/隱藏感測器統計資訊
y – 顯示/隱藏硬碟溫度統計資訊
l – 顯示/隱藏日誌(log)
b – 切換網路 I/O 單位(Bytes/bits)
w – 刪除警告日誌
x – 刪除警告和嚴重日誌
l – 切換全局 CPU 使用情況和每個 CPU 的使用情況
h – 顯示/隱藏這個幫助畫面
t – 以組合形式瀏覽網路 I/O
u – 以累計形式瀏覽網路 I/O
q – 退出('ESC' 和 'Ctrl&C' 也可以)
常用選項: -b:以 Byte 為單位顯示網卡數據速率 -d:關閉磁碟 I/O 模組 -f /path/to/somefile:設定輸入文件位置 -o {HTML|CSV} :輸出格式 -m:禁用 mount 模組 -n:禁用網路模組 -t #:延遲時間間隔 -1 :每個 CPU 的相關數據單獨顯示
C/S 模式下運行 glances 命令 伺服器模式: glances -s -B IPADDR IPADDR:指明監聽的本機哪個地址 客戶端模式: glances -c IPADDR IPADDR:要連入的伺服器端地址
dstat 命令詳解:系統資源統計
dstat 是一個可以取代vmstat,iostat,netstat和ifstat這些命令的多功能產品。
# yum install dsta //安裝
dstat [-afv] [options..] [delay [count]
常用命令選項:
-c, --cpu:顯示cpu相關資訊;
-C #,#,...,total
-d, --disk:顯示磁碟的相關資訊
-D sda,sdb,...,tobal
-g:顯示page相關的速率數據;
-m:Memory的相關統計數據
-n:Interface的相關統計數據;
-p:顯示process的相關統計數據;
-r:顯示io請求的相關的統計數據;
-s:顯示swapped的相關統計數據;
--tcp
--udp
--raw
--socket
--ipc
--top-cpu:顯示最佔用CPU的進程;
--top-io:最佔用io的進程;
--top-mem:最佔用記憶體的進程;
--top-latency:延遲最大的進程;
示例1:記憶體資源使用情況
# dstat -glms --top-mem
示例2:CPU資源使用情況
# dstat -cyl --proc-count --top-cpu
iotop 命令詳解:
iotop 命令是一個用來監視磁碟 I/O 使用狀況的 top 類工具 iotop 具有與 top 相似的 UI,其中包括 PID、用戶、I/O、進程等相關資訊,可查看每個進程是如何使用 IO iotop 輸出: 第一行:Read 和 Write 速率總計 第二行:實際的 Read 和 Write 速率 第三行:參數如下: 執行緒 ID (按 p 切換為進程 ID ) 優先順序 用戶 磁碟讀速率 磁碟寫速率 swap 交換百分比 IO 等待所佔的百分比 執行緒/進程命令
iotop 常用參數: -o,--only 只顯示正在產生I/O的進程或執行緒,除了傳參,可以在運行過程中按o生效 -b,--batch 非交互模式,一般用來記錄日誌 -n NUM,--iter=NUM 設置監測的次數,默認無限。在非交互模式下很有用 -d SEC,--delay=SEC 設置每次監測的間隔,默認1秒,接受非整形數據例如1.1 -p PID,--pid=PID 指定監測的進程/執行緒 -u USER,--user=USER 指定監測某個用戶產生的I/O -P,--processes 僅顯示進程,默認iotop顯示所有執行緒 -a,--accumulated 顯示累積的I/O,而不是頻寬 -k,--kilobytes 使用kb單位,而不是對人友好的單位。在非交互模式下,腳本編程有用
iotop 常用參數和快捷鍵:
-t,--time 加上時間戳,非交互非模式
-q, --quiet 禁止頭幾行,非交互模式,有三種指定方式
-q 只在第一 次監測時顯示列名
-qq 永遠不顯示列名
-qqq 永遠不顯示I/0匯總
交互按鍵:
left 和 right 方向鍵:改變排序
r:反向排序
0:切換至選項--only
p:切換至--processes選項
a:切換至--accumulated選項
q:退出
i:改變執行緒的優先順序
nload 查看網路實時吞吐量:
nload 是一個實時監控網路流量和頻寬使用情況,以數值和動態圖展示進出的流量情況
安裝:yum -y install nload (EPEL 源) 介面操作: 上下方向鍵、左右方向鍵、enter 鍵或者 tab 鍵都就可以切換查看多個網卡的流量情況 按 F2 顯示選項窗口 按 q 或者 Ctrl+C 退出 nload
示例: nload:默認只查看第一個網路的流量進出情況 nload eth0 eth1:在 nload 後面指定網卡,可以指定多個 設置刷新間隔:默認刷新間隔是 100 毫秒,可通過-t 命令設置刷新時間(單位是毫秒) nload -t 500 eth0 設置單位:顯示兩種單位一種是顯示 Bit/s、一種是顯示 Byte/s,默認是以 Bit/s,也可不顯示/s -u h|b|k|m|g|H|B|K|M|G 表示的含義:h:auto,b:Bit/s,k:kBit/s,m:MBit/s,H:auto,B:Byte/s,K:kByte/s,M:MByte/s nload-u M eth0
lsof:list open files 查看當前系統文件的工具
在 linux 環境下,一切皆文件,用戶通過文件不僅可以訪問常規數據還可以訪問網路連接和硬體如傳輸控制協議(TCP)和用戶數據報協議(UDP)套接字等,系統在後台都為該應用程式分配了一個文件描述符 命令參數: -a:列出打開文件存在的進程 -c<進程名>:列出指定進程所打開的文件 -g:列出 GID 號進程詳情 -d<文件號>:列出佔用該文件號的進程 +d<目錄>:列出目錄下被打開的文件 +D<目錄>:遞歸列出目錄下被打開的文件
lsof示例:
進程管理:
查看由登陸用戶啟動而非系統啟動的進程
lsof /dev/pts/1
指定進程號,可以查看該進程打開的文件
Isof -p 9527
文件管理:
查看指定程式打開的文件
Isof -c httpd
查看指定用戶打開的文件
Isof -u root | more
查看指定目錄下被打開的文件
lsof +D /var/log/
lsof +d /var/log/
參數 +D 為遞歸列出目錄下被打開的文件,參數+d為列出目錄下被打開的文件
恢復刪除文件:
lsof | grep delete # 查看打開文件(被誤刪除),看到進程編號,如:11863
ll /proc/11863/fd # 查看文件描述符,如 4(已被刪除)
cat /proc/11863/fd/4 > /data/m.txt # 重定向找迴文件
查看所有網路連接:
lsof -i -n
lsof [email protected]
通過參數 -i 查看網路連接的情況,包括連接的ip、埠等以及一些服務的連接情況,例如:sshd等。也可以通過指定 ip 查看該 ip 的網路連接情況。
查看埠連接情況:
lsof -i :80 -n
通過參數 -i:埠 可以查看埠的佔用情況,-i參數還有查看協議,ip的連接情況等
查看指定進程打開的網路連接:
lsof -i -n -a -p 9527
參數-i、-a、-p等,-i查看網路連接情況,-a查看存在的進程,-p指定進程
查看指定狀態的網路連接:
lsof -n -P -i TCP -s TCP:ESTABLISHED
-n:no host names,-P:no port names,-i TCP指定協議,-s指定協議狀態通過多個參數可以清晰的查看網路連接情況、協議連接情況等
15、進程管理工具
kill 命令:向進程發送控制訊號,以實現對進程管理每個訊號對應一個數字,訊號名稱以 SIG 開頭(可省略),不區分大小寫
顯示當前系統可用訊號:kill-I 或者 trap -l 常用訊號: man 7 signal 0) 訊號檢查某個進程是否正常 1) SIGHUP 無須關閉進程而讓其重讀配置文件 2) SIGINT 中止正在運行的進程,相當於 Ctrl+C 3) SIGQUIT 相當於 ctrl+\ 9) SIGKILL 強制殺死正在運行的進程 15) SIGTERM 終止正在運行的進程,默認 18) SIGCONT 繼續運行 19) SIGSTOP 後台休眠 指定訊號的方法: (1)訊號的數字標識:1,2,9 (2)訊號完整名稱:SIGHUP (3)訊號的簡寫名稱: HUP
示例: 先 ps aux 查到該進程 ID,kill -1 [進程 ID],發訊號 kill -2 `pidof bc` # 中止 bc 程式 按 PID:kill [-SIGNAL] pid ... kill -n SIGNAL pid kill -S SIGNAL pid 按名稱:killall [-SIGNAL] comm... # 例:killall httpd 按模式:pkill [options] pattern # 支援正則 -SIGNAL -u uid:effective user,生效者 -U uid:realuser,真正發起運行命令者 -t terminal:與指定終端相關的進程 -l:顯示進程名(pgrep 可用) -a:顯示完整格式的進程名(pgrep 可用) -P pid:顯示指定進程的子進程
16、作業管理
Linux 的作業控制:
前台作業:通過終端啟動,且啟動後一直佔據終端
後台作業:可通過終端啟動,但啟動後即轉入後台運行(釋放終端)
讓作業運行於後台:
(1)運行中的作業:Ctrl+z,停止狀態
(2)尚未啟動的作業:COMMAND &
後台作業雖然被送往後台運行,但其依然與終端相關;退出終端,將關閉後台作業。如果希望送往後台後,剝離與終端的關係:
nohup COMMAND &> /dev/null & screen ; COMMAND
查看當前終端所有作業: jobs
作業控制:
fg [[%]JOB_NUM]:把指定的後台作業調回前台 bg [[%]JOB_ NUM]:讓送往後台的作業在後台繼續運行 kill [%JOB_ NUM]:終止指定的作業 killall -19 ping # 19 訊號將後台變為後台休眠狀態 killall -18 ping # 18 訊號將後台休眠變為後台執行
並行運行:同時運行多個進程,提高效率
方法 1: vi all.sh f1.sh& f2.sh& f3.sh&
方法 2: (f1.sh&);(f2.sh&);(f3.sh&)
方法 3: { f1.sh& f2.sh& f3.sh& } { ping 127.1& ping 127.2& ping 127.3& }