Linux 進程

進程: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>目錄下。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章