進程:process, 過程(有開始有結束)
MMU: Memory Management Unit
內存保護機制
實現內存虛擬化:
CPU 32bit: 2^32=4GB 所以在32位架構上每一個程序都認爲自己是有4G內存可以使用的。
這種叫做線性地址空間
物理地址空間:RAM+ROM
CPU 一加電就會讀讀ROM裏面的程序使主機啓動,如果沒有ROM主機就無法啓
MMU這種機制將內存地址一個一個的分成頁框,能夠存儲固定大小單元的數據, 每個單元就成爲頁(Page)。
4G的內存,其中給了1G是給內核使用的,Kernel space 在內存空間的最高段。其他3G分給指令(text segment),數據(data segment),變量段(BSS segment),堆(heap),內存映射段(Memory mapping segment)棧(stack)。
程序是靜態的,而進程是動態的。
進程樹:pstree
進程:init(1) --> fork() -->
所以進程都來自init,除了init進程沒有父進程,其他都有父進程。
init進程是由內核創建的。子進程由父進程創建,父進程由init進程創建。
進程間通信:IPC, Inter Process Communication
signal(信號), shm(共享內存), semerphor
進程分爲兩類:
CPU-Bound: CPU密集型進程(需要大量佔用CPU的進程)
IO-Bound:IO密集型進程(需要大量佔用IO的進程)
進程分爲三類:
批處理進程(通常是CPU密集型進程如服務類進程或者守護進程)
實時進程(以實時爲主要目的)
交互式進程
調度器:
進程優先級:
動態優先級:
懲罰措施:
靜態優先級:用戶類進程
100-139:數字越小,優先級越高;
nice值:-20, 19
100, 139
實時優先級:內核類線程
1-99:數字越大,優先級越高;
Linux 2.6: O(1)
進程切換:Context Switch, 上下文切換
內核模式,用戶模式
內核空間,用戶空間
ring0: 特權指令,敏感指令
ring3:普通指令 --> 系統調用
IO:
poll: 輪詢, 忙等待;
interupt: 中斷, 中斷的上半部和下半部 (當某個信號到來的時候會中斷通知CPU),一箇中斷會打打斷一個進程的運行過程。
中斷就一些不可預知的但是又必須處理的信號。
DMA:
進程的狀態:
Ready:
Running:
5ms, 2ms,
Sleeping(當外部條件沒能滿足的時候被切換出去了)
Interruptable Sleeping (可中斷睡眠,可以叫醒繼續運行)
Uninterruptable Sleeping(非可中斷睡眠,可能是因爲外部的IO還沒有準備好,所以叫不醒它)
Stopped: (停止狀態,叫它也不會醒)
Zombie: 僵死態
COW: Copy On Write: 寫時複製;
內存泄露:內存分出去的可用空間收不回來,導致沒有可用空間使用了。
線程是進程的一個子單位,在linux中 線程只是被簡化的進程
進程管理類的命令:
pstree, ps, top, vmstat, htop, pmap
pstree: 查看進程樹;
ps: 顯示系統向前進程狀態的命令;process status
進程:
跟終端相關的進程
跟終端無關的進程
a: 所有跟終端相關的進程
x: 所有跟終端無關的進程
STAT:
S:可中斷睡眠
D:不可中斷睡眠
R:運行或可運行;
T:停止
Z:僵死
s: session leader
l: 多線程進程;
+: 前臺進程;
N: 低優先級進程;
<: 高優先級進程;
u: 以用戶爲中心顯示進程相關信息
%CPU: cputime/realtime
%MEM:
VSZ: Virtual memory SiZe線性地址大小
RSS: 常駐內存集;
PSR:表示運行在哪個cpu上
-ef:
-e: 顯示所有進程;entire progress
-f: 完整格式列表;full format
-eFH
-F:顯示額外信息;
-H: 顯示進程層次關係;
-o 要顯示的字段: 自定義顯示格式
ps axo pid,command
pgrep pattern: process grep
例如:pgrep bash
選項:
-U USERNAME:顯示相關用戶的進程;
-G GROUPNAME:相關組的進程;
pidof: 找到某個程序的進程ID pidof:process pid of program.
top:是個交互式命令。默認是按cpu 來排序的
參數:
M: 按內存空間佔用大小排序;
P:按CPU時間佔用大小排序;
T:按累計時間排序;
k: 殺死一個進程;
m: 是否顯示內存摘要信息;
t: 是否顯示CPU和進程的統計信息;
l: 是否顯示負載信息
q: 退出
顯示信息:
us,sy,ni,id,wa,hi,si,st,
us:user 用戶佔用cpu百分比
sy:系統內核佔用cpu百分比
ni:表示調整nice值佔用cpu百分比
i:idle表示空閒cpu百分比
wa:wait表示等待IO 完成所佔cpu百分比
hi:硬件中斷所佔cpu百分比
si:軟件中斷所佔cpu百分比
st:被偷走時間所佔cpu百分比
PID:進程號
USER:用戶
PR:priority優先級RT:實時優先級 , 數子表示優先級
NI:nice值
VIRI:虛擬優先級
RES:實際優先級
SHR:share memory共享內存級
S:status 狀態
TIME+:進程使用cpu時間的總計,單位是百分之一秒。
COMMAND:有哪個命令啓動這個進程的
選項:
-d #: 刷新延遲;
-b : 批次顯示;
-n #: 指定批次顯示時顯示的批數;
htop: 增強版top,比top更好用,系統沒有的話需要安裝,
ps、pstree、pidof、pgrep、top、htop
vmstat:virtual memory status
procs
r: 運行或等待CPU時間片的進程的個數;
b: 被阻塞(通常爲等待IO完成)的進程隊列的長度;b表示block
memory
swpd: 從物理內存交換至交換分區的數據量;
free: 未使用的物理內存空間;
buff: buffer cache的空間大小;通常是緩存寫操作相關的數據;
cache: page cache的空間大小;通常是緩存讀操作的相關數據;
swap:
si: swap in, 數據進入交換分區數據量,即從內存至交換分區中去;(kb/s)
so: swap out, 數據離開交換分區數據量,即從交換分區至內存;
io:
bi: block in,從塊設備讀入的數據量, (kb/s)
bo: block out,保存至塊設備的數據量, (kb/s)
system:
in: interrupt,中斷髮生的速率,通常意爲每秒多個次中斷請求發生;
cs: context switch, 上下文切換的速率;
cpu:
us: 用戶進程所佔用CPU時間的百分比;
sy: 內核
id: CPU空閒百分比;
wa: CPU用於等待IO完成的時間百分比;
st: 被虛擬化佔去的時間百分比;
sar -u
sar -P ALL 顯示所有cpu相關信息
iostat -c : 也能顯示CPU 相關信息的
dstat -c :指定顯示cpu的信息
dstat -C 0,3
進程間通信:IPC :只要涉及到進程間交換數據都叫進程間通信。
共享內存,shm
信號:signal
引用信號的方式有三種:1
1)引用信號名稱
2)引用信號ID號
3)引用信號名稱簡寫,
信號:給別人發生簡短的信息。以下信號需要記住:
1:SIGHUP, 讓進程不用終止,而重讀其配置文件;
2: SIGINT, 中斷正在運行的進程, 相當於Ctrl+c;
9:SIGKILL, 殺死; 類似於祕密殺死
15: SIGTERM, 終止; 類似於人道殺死
19: SIGSTOP, 停止; 讓進程停一會
18:SIGCONT:喚醒,可以把停止的進程再次喚醒繼續運行。
向其它進程傳遞信號,使用kill
kill -信號 PID #根據PID 來殺死進程
kill -9 2031 = kill -SIGKILL 2031 #我們可以使用數字或者名稱全名或者名稱簡稱
killall -信號 進程名 #根據名稱來殺死進程
killall -9 crond #殺死所有crond進程,這裏必須使用進程名了不能使用進程ID
killall5 #向所有進程發生命令。
kill -l #查看支持的信號
調整進程nice值:
普通用戶:調大數字,調低優先級;
-20, 19 #默認nice值爲0,nice值越小優先級越高
100, 139 #默認優先級爲120 ,數字越大優先級越低。
nice -n # COMMAND
renice # PID #把某個PID的進程的nice值重新調整爲#
Linux作業控制:
前臺:佔用着終端;前臺作業
後臺:無須佔用終端;
前臺-->後臺:Ctrl+z #但是作業此時爲停止狀態。
後臺-->前臺:fg %JOB_ID #
jobs 查看後臺作業,我就是經常使用ctrl+z 來退出文本編輯,看來是不對的。只是把當前的作業送傲後臺而已。
我們可以通過#fg %JOB_ID 來把後臺進程調回前臺。
bg [[%]JOB_ID]:讓作業在後臺運行;
啓動時,讓作業直接運行於後臺,它是可以繼續在後臺運行的,只有把進程從前臺送到後臺時,進程狀態爲stoped 停止的。
# COMMAND & #通過在命令後面加上&可以把命令放在後臺執行。
# nohup COMMAND & #退出終端也可以繼續在後臺執行, nohup 不需要終端
作業也可被終止:
kill [%JOB_ID] #結束作業,需要在kill命令後面加% 再加上作業id
axel -n 5 -o ./ http://a.b.c.d/abc.iso &
screen:#把當前終端分成多個屏幕,默認沒裝,這樣就可以實現把某個需要長時間運行的任務放在screen中運行,這樣即使關閉了當前終端,
任務也會在screen中繼續運行, 當再次登錄終端時可以通過screen -r 回到screen中。
screen #打開一個screen
screen -ls #查看所有屏幕
screen -r SCREEN_ID #回到某個screen
exit #終止screen
Linux終端:
控制檯:/dev/console
物理終端:
虛擬終端:/dev/tty[1-6]
模擬終端: /dev/pts/#
串行終端: /dev/ttyS#
練習:
1、如何獲取當前系統上下文切換的次數?sar、iostat或dstat是否可以?
/proc:內核映射,僞文件系統;
PID #每個進程啓動的時候在/proc目錄下面有一個以進程pid爲名稱的目錄。這個目錄裏面存放着這個進程相關屬性,
每個進程目錄裏面都有一個maps。它記錄着當前進程所依賴的庫文件在內存中的地址。
# cat /proc/PID/maps #查看進程運行的物理地址空間映射;
# pmap PID: #查看進程運行的物理地址空間映射;
多處理器:
mpstat
補充資料:關於mmap
系統調用mmap()可以將某文件映射至內存(進程空間),如此可以把對文件的操作轉爲對內存的操作,以此避免更多的lseek()與read()、write()操作,這點對於大文件或者頻繁訪問的文件而言尤其受益。
1、 Linux採用了投機取巧的分配策略,用到時,才分配物理內存。也就是說進程調用brk()或mmap()時,只是佔用了虛擬地址空間,並沒有真正佔用物理內存。這也正是free –m中used並不意味着消耗的全都是物理內存。
2、 mmap()通過指定標誌(flag) MAP_ANONYMOUS來表明該映射是匿名內存映射,此時可以忽略fd,可將它設置爲-1。如果不支持MAP_ANONYMOUS標誌的類unix系統,可以映射至特殊設備文件/dev/zero實現匿名內存映射。
3、 調用mmap()時就決定了映射大小,不能再增加。換句話說,映射不能改變文件的大小。反過來,由文件被映射部分,而不是由文件大小來決定進程可訪問內存空間範圍(映射時,指定offset最好是內存頁面大小的整數倍)。
4、通常使用mmap()的三種情況.提高I/O效率、匿名內存映射、共享內存進程通信。
mmap將一個文件或者其它對象映射進內存。文件被映射到多個頁上,如果文件的大小不是所有頁的大小之和,最後一個頁不被使用的空間將會清零。
當使用mmap映射文件到進程後,就可以直接操作這段虛擬地址進行文件的讀寫等操作,不必再調用read,write等系統調用.但需注意,直接對該段內存寫時不會寫入超過當前文件大小的內容.
採用共享內存通信的一個顯而易見的好處是效率高,因爲進程可以直接讀寫內存,而不需要任何數據的拷貝。對於像管道和消息隊列等通信方式,則需要在內核和用戶空間進行四次的數據拷貝,而共享內存則只拷貝兩次數據:一次從輸入文件到共享內存區,另一次從共享內存區到輸出文件。
進程:
使用命令 pmap -x <pid> 可以查看進程的內存佔用信息; lsof -a -p <pid> 可以查看一個進程打開的文件信息。ps -Lf <pid> 可以查看進程的線程數。
另外procfs也是一個分析進程結構的好地方。procfs是一個虛擬的文件系統,它把系統中正在運行的進程都顯現在/proc/<pid>目錄下。