七、Linux脚本进阶和进程管理
一、進程
進程:init(1)-->系統的第一個進程,通過fork調用其他進程,自身由內核發起。
通過pstree可以查看進程之間的父子關系。
[root@localhost?~]#?pstreeinit─┬─NetworkManager─┬─dhclient│????????????????└─{NetworkManager}├─abrtd├─acpid├─atd├─auditd───{auditd}├─crond├─cupsd├─dbus-daemon───{dbus-daemon}├─hald─┬─hald-runner─┬─hald-addon-acpi│??????│?????????????└─hald-addon-inpu│??????└─{hald}├─master─┬─pickup│????????└─qmgr├─6*[mingetty]├─modem-manager├─rsyslogd───3*[{rsyslogd}]├─sshd───sshd───bash───pstree├─tpvmlp├─udevd───2*[udevd]├─vmtoolsd───{vmtoolsd}├─vmware-vmblock-───4*[{vmware-vmblock}]└─wpa_supplicant1、進程的分類
內存地址空間分配使用情況說明
1
進程間通訊:IPC inter process communication
不同程序調用相同的庫文件,就需要進程間通訊。
進程分為兩類:
CPU-bound:CPU密集型進程
IO-bound:IO密集型進程
進程按處理時間分:
批處理進程
實時進程
交互式進程
2、進程間工作原理
進程切換
為什么要有進程切換
因為一個系統要提供多個進程同時工作,也就是多任務的概念,那么每個程序可能由多個進程組成,每個進程又分配了優先級和時間片,如果一個進程時間片用完,就要給另一個進程使用了,另一種情況是,一個進程的工作需要調用另一個進程來協助完成,再有就是被搶占。這三種方式都需要進程切換。
如何實現進程切換
進程進行切換前需要有現場保護的一個工作,對方進程完畢切換回來還需要一個現場恢復的過程。
進程如果需要切換到其他進程上需要由內核來完成,自己不能直接處理,這個時候就有了系統調用的概念,就是內核幫助進程完成某些工作,cpu的工作模式分為內核模式(ring0)和用戶模式(ring3),內核會依據級別來確定是工作在內核模式上還是用戶模式上,所以說有系統調用就必然有模式切換。
什么是模式切換?
就是在進行系統調用的時候產生的對cpu工作模式的切換,帶內核工作完成后再將工作還給進程。
模式切換不是上下文切換,什么是上下文切換呢?
上下文切換是指一個進程結束,執行另一個進程或者被搶奪的情況,稱為上下文切換。
3、IO操作
什么是io(輸入輸出)
一個系統的運行,是要為人服務的,就是說人可以進行輸入操作,并通過輸出獲得結果,這個就是io操作。
系統如何識別io的操作
io操作有很多,可以是鍵盤輸入,批處理命令,遠程操作等等,內核如何識別這些操作,并準確處理呢,
首先如何獲取io操作,早期是通過忙等待的方式,就是保留一個資源給io接口,等待它的操作指令,第二種是輪詢,定期查看io接口是否有輸入操作。第三種是中斷,就是當有io操作時發送一個中斷信號給內核,要求內核處理,這里就可以知道io操作的優先級還是比較高的。
4、優先級
如何設置進程的運行等級?調度器!
? ? ? ? ?進程優先級:
? ? ? ? ? ? ? ?動態優先級
? ? ? ? ? ? ? ?靜態優先級:100-139 數值越小優先級越高
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?可以通過nice值來手動調整,-20,19。
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?普通用戶只可以調大數字,降低優先級。
? ? ? ? ? ? ? ? ? ? ? ? ? ??? ? ? ? ? 用法:nice -n # command
? ? ? ? ? ? ? ?實時優先級:調度實時進程,1-99 數值越大優先級越高
5、進程的狀態
ready、running、sleeping、stopped,zombie(僵死狀態)
多cpu如何應用?
一個程序要運行,(只)開啟一個進程的,通常一個程序是只有一個數據流的(按照程序編寫的順序自上向下執行),并只會占用一個cpu的內核,當有多個cpu同時工作的情況,如何利用cpu的優勢呢,通常有兩種情況:1、將多個進程分配到多個cpu內核上,每個內核就分配到了一定數量的進程,達到了合理分配資源的目的。2、如果只有一個程序占用大量的資源,要給他分配多個cpu內核如何操作呢,就是需要程序在編寫的時候,允許多個數據流同時進行,這樣在程序創建進程的時候,就可以在一個進程中創建多個線程,每個線程就是一個數據流。linux對線程的支持并不是很好,表現的最終形式就是輕量級進程,最終體現的還是“進程”哦。
基于線程的訪問優勢就是它是進程的子集,所有在訪問重復資源的時候,不需要重復范圍,可以通過其他線程上訪問,更加快捷,非常適用于web服務。
二、進程管理
進程管理類的命令:
pstree、ps、top、vmstat、htop
1、pstree:查看進程樹
[root@localhost ~]# pstree
init─┬─NetworkManager
?? ? ├─abrtd
?? ? ├─acpid
?? ? ├─atd
?? ? ├─auditd───{auditd}
?? ? ├─automount───4*[{automount}]
?? ? ├─bluetoothd
?? ? ├─certmonger
?? ? ├─console-kit-dae───63*[{console-kit-da}]
2、PS詳解
ps:顯示當前進程狀態的命令;靜態顯示。
[root@localhost ~]# ps -efH
UID ? ? ? ? PID ? PPID? C STIME TTY? ? ? ? ? TIME CMD
root? ? ? ? ? 1? ? ? 0? 0 May15 ?? ? ? ? 00:00:01 /sbin/init
root? ? ? ? 575? ? ? 1? 0 May15 ?? ? ? ? 00:00:00 ? /sbin/udevd -d
root ? ? ? 2121? ? 575? 0 May15 ?? ? ? ? 00:00:00 ? ? /sbin/udevd -d
root ? ? ? 2122? ? 575? 0 May15 ?? ? ? ? 00:00:00 ? ? /sbin/udevd -d
root ? ? ? 1535? ? ? 1? 0 May15 ?? ? ? ? 00:00:00 ? auditd
root ? ? ? 1569? ? ? 1? 0 May15 ?? ? ? ? 00:00:00 ? /sbin/rsyslogd -i /var/run/s
rpc? ? ? ? 1620? ? ? 1? 0 May15 ?? ? ? ? 00:00:00 ? rpcbind
常用參數:
-a所有和終端相關的進程 ? ?
-x所有和終端無關的進程,用?來表示和終端無關
-u以用戶為中心顯示進程
-e:顯示所有進程
-f:完整格式列表
? ? ? ??? ? ppid:父進程號
-F:顯示額外信息
? ? ? ? ? ? psr:表示運行在那顆cpu上
-H:顯示進程間的父子關系
-o:自定義顯示格式
進程條目:
? ? ? ? stat:
? ? ? ? ? ? ? ? ? ?S:可中斷睡眠狀態,
? ? ? ? ? ? ? ? ? ?D:不可中斷的睡眠。
? ? ? ? ? ? ? ? ? ?R:運行或可運行
? ? ? ? ? ? ? ? ? ?T:停止
? ? ? ? ? ? ? ? ? ?Z:僵死
? ? ? ? ? ? ? ? ? ?s:session leader 一個進程的主要進程
? ? ? ? ? ? ? ? ? ?l:多線程進程
? ? ? ? ? ? ? ? ? ?+:前臺進程
? ? ? ? ? ? ? ? ? ?N:低優先級進程
? ? ? ? ? ? ? ? ? ?<:高優先級進程
time:運行時長
command:進程發起者,命令
vsz:線性地址空間大小,非實際占用大小
rss:實際占用空間大小
%cpu:進程占用cpu時間比
paid:父進程號碼
stime:第一次啟動時間
time:運行時長
PSR:表示運行在多cpu的那個cpu內核上
u:以用戶為中心顯示進程的相關信息
TTY:
??控制臺:/dev/console
??虛擬終端:/dev/tty1-6,
??模擬終端:遠程連接的終端 /dev/pts/0
??串行終端:/dev/ttys
ps命令詳解:http://www.cnblogs.com/wangkangluo1/archive/2011/09/23/2185938.html
3、pgrep詳解
?顯示指定的進程信息。
? ?-U:username 顯示相關用戶的進程
? ?-G:groupname 顯示組的進程
? ?-l:查看指定程序或進程的進程號
[root@localhost ~]# pgrep -U root
1
2
3
4
5
4、pidof
顯示某進程的進程號
[root@localhost ~]# pidof sshd
5449 1878
5、top詳解
[root@localhost ~]# top
top - 01:18:07 up 19:56,? 2 users,? load average: 0.00, 0.00, 0.00
Tasks:? 99 total, ? 1 running,? 98 sleeping, ? 0 stopped, ? 0 zombie
Cpu(s):? 0.0%us,? 0.0%sy,? 0.0%ni,100.0%id,? 0.0%wa,? 0.0%hi,? 0.0%si,? 0.0%st
Mem: ? 1004768k total, ? 230948k used, ? 773820k free,? ? 33972k buffers
Swap:? 2031612k total,? ? ? ? 0k used,? 2031612k free,? ? 69424k cached
?? PID USER? ? ? PR? NI? VIRT? RES? SHR S %CPU %MEM? ? TIME+? COMMAND ? ? ? ? ?
?? ? 1 root? ? ? 20 ? 0 19364 1540 1228 S? 0.0? 0.2 ? 0:01.32 init ? ? ? ? ? ? ?
?? ? 2 root? ? ? 20 ? 0 ? ? 0? ? 0? ? 0 S? 0.0? 0.0 ? 0:00.00 kthreadd ? ? ? ? ?
?? ? 3 root? ? ? RT ? 0 ? ? 0? ? 0? ? 0 S? 0.0? 0.0 ? 0:00.00 migration/0? ? ?
條目詳解
load average:每隔5/10/15分鐘的隊列長度。一般是一個小數
cpu:us:用戶空間程序占用%
? ? ? ? ? sy:內核空間程序占用%,她與us的合理比例是7:3,就是us占70%,sy占30%
? ? ? ? ? ni:調整nice值
? ? ? ? ? id:cpu空閑%
? ? ? ? ? wa:(wait)等待磁盤io完成輸入輸出工作所占據的時間比例
? ? ? ? ? hi:硬件中斷占據的百分比
? ? ? ? ? si:軟中斷占據的百分比
? ? ? ? ? st:被偷走的時間,虛擬機占用運行的時間
PR:優先級 priority
NI:nice值
virt:虛擬內存級
res:實際內存級
shar:共享內存優先級
s:狀態stats
%cpu:自從上次刷新到現在cpu被此進程占用的百分比。
選項和參數:
top是交互式命令,通過輸入不同的字母顯示不同的信息,實際上就是條目的第一個縮寫,比如
M:按內存空間占用大小排序
P:按cpu時間占用大小排序
T:按累計時間排序
k:殺死一個進程,輸入后需要制定kill 后面的選項1-15,常用是9 強制殺死。
m、p、l用于是否顯示抬頭的相關信息。
q:退出
-d #:刷新時間
-b:批次顯示
-n #:指定批次顯示的次數
6、vmstat
查看服務器cpu使用情況,內存、虛擬內存使用情況和磁盤讀寫情況。
[root@localhost ~]# vmstat
procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu-----
?r? b ? swpd ? free ? buff? cache ? si ? so? ? bi? ? bo ? in ? cs us sy id wa st
?0? 0? ? ? 0 164752 1484028 449036? ? 0? ? 0 ? ? 0 ? 138 ? 10 ? 18? 0? 0 100? 0? 0
[root@localhost ~]# vmstat
procs:
r:運行或等待cpu時間片的進程的個數
b:被阻塞的進程隊列的長度
memory:
swpd?虛擬內存(swap)已使用的大小,如果大于0,表示你的機器物理內存不足了,如果不是程序內存泄露的原因,那么你該升級內存了或者把耗內存的任務遷移到其他機器。
free?? 空閑的物理內存的大小,我的機器內存總共8G,剩余3415M。
buff?? Linux/Unix系統是用來存儲,目錄里面有什么內容,權限等的緩存,我本機大概占用300多m
cache?cache直接用來記憶我們打開的文件,給文件做緩沖,我本機大概占用300多M(這里是Linux/Unix的聰明之處,把空閑的物理內存的一部分拿來做文件和目錄的緩存,是為了提高 程序執行的性能,當程序使用內存時,buffer/cached會很快地被使用。)
si??每秒從磁盤讀入(放到swap中的數據量)虛擬內存的大小,如果這個值大于0,表示物理內存不夠用或者內存泄露了,要查找耗內存進程解決掉。我的機器內存充裕,一切正常。
so??每秒虛擬內存寫入磁盤的大小(從swap中讀取的數據量),如果這個值大于0,同上。
bi??塊設備(磁盤)每秒接收的塊數量,這里的塊設備是指系統上所有的磁盤和其他塊設備,默認塊大小是1024byte,我本機上沒什么IO操作,所以一直是0,但是我曾在處理拷貝大量數據(2-3T)的機器上看過可以達到140000/s,磁盤寫入速度差不多140M每秒
bo?塊設備每秒發送的塊數量,例如我們讀取文件,bo就要大于0。bi和bo一般都要接近0,不然就是IO過于頻繁,需要調整。
in?每秒CPU的中斷次數,包括時間中斷
cs?每秒上下文切換次數,例如我們調用系統函數,就要進行上下文切換,線程的切換,也要進程上下文切換,這個值要越小越好,太大了,要考慮調低線程或者進程的數目,例如在apache和nginx這種web服務器中,我們一般做性能測試時會進行幾千并發甚至幾萬并發的測試,選擇web服務器的進程可以由進程或者線程的峰值一直下調,壓測,直到cs到一個比較小的值,這個進程和線程數就是比較合適的值了。系統調用也是,每次調用系統函數,我們的代碼就會進入內核空間,導致上下文切換,這個是很耗資源,也要盡量避免頻繁調用系統函數。上下文切換次數過多表示你的CPU大部分浪費在上下文切換,導致CPU干正經事的時間少了,CPU沒有充分利用,是不可取的。
us?用戶進程占用CPU時間的百分比,我曾經在一個做加密解密很頻繁的服務器上,可以看到us接近100,r運行隊列達到80(機器在做壓力測試,性能表現不佳)。
sy?系統進程占用CPU時間的百分比,如果太高,表示系統調用時間長,例如是IO操作頻繁。
id??空閑 CPU時間,一般來說,id + us + sy = 100,一般我認為id是空閑CPU使用率,us是用戶CPU使用率,sy是系統CPU使用率。
wt?cpu等待IO完成的時間。
st:被虛擬化偷走的時間
選項:
vmstat delay count:設置vmstat顯示的刷新的時間間隔和顯示次數 vmstat 2 2
[root@localhost ~]# vmstat 2 2
procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu-----
?r? b ? swpd ? free ? buff? cache ? si ? so? ? bi? ? bo ? in ? cs us sy id wa st
?0? 0? ? ? 0 164612 1484036 449036? ? 0? ? 0 ? ? 0 ? 138 ? 10 ? 18? 0? 0 100? 0? 0
?0? 0? ? ? 0 164612 1484036 449036? ? 0? ? 0 ? ? 0 ? ? 0 ? 71 ? 78? 0? 0 100? 0? 0
每個兩秒顯示一次,一共顯示兩次。
7、sar (system activity reporter)
用來收集、顯示保存系統活動信息及報告。
-u:
-P:指定顯示cpu的信息
linux sar命令詳解
8、iostat:顯示系統性能相關信息,硬盤讀寫情況。
[root@localhost ~]# iostat
Linux 4.6.0 (localhost.localdomain)?2016年05月18日?_x86_64_(1 CPU)
avg-cpu:? %user ? %nice %system %iowait? %steal ? %idle
?? ? ? ? ? 0.03? ? 0.00? ? 0.14? ? 0.02? ? 0.00 ? 99.81
Device:? ? ? ? ? ? tps ? Blk_read/s ? Blk_wrtn/s ? Blk_read ? Blk_wrtn
sda ? ? ? ? ? ? ? 1.75? ? ? ? 25.03 ? ? ? ? 2.41 ? ? 592778? ? ? 57170
dm-0? ? ? ? ? ? ? 1.82? ? ? ? 24.63 ? ? ? ? 2.41 ? ? 583402? ? ? 57152
dm-1? ? ? ? ? ? ? 0.01 ? ? ? ? 0.11 ? ? ? ? 0.00 ? ? ? 2600? ? ? ? ? 0
9、dstat -c 顯示cpu詳細 實時顯示
[root@localhost ~]# dstat
----total-cpu-usage---- -dsk/total- -net/total- ---paging-- ---system--
usrsysidlwaihiqsiq|?read??writ|?recv??send|? in???out?|?int???csw?
? 0 ? 0?100?? 0 ? 0 ? 0|? 15k?1602B|?? 0 ? ? 0?|?? 0 ? ? 0?|?103???127?
? 0 ? 0?100?? 0 ? 0 ? 0|?? 0??? 28k|2067B?1234B|?? 0 ? ? 0?|?101??? 97?
? 0 ? 0?100?? 0 ? 0 ? 0|?? 0 ? ? 0?|1612B??452B|?? 0 ? ? 0?|? 80??? 79?
三、信號
引用信號的方法:通過數字、信號名、簡寫。
顯示信號:kill -l
常用信號:
1:sighup:進程不用終止,而可以重讀配置文件。對于在線服務可以使用。
2:sigint:中斷正在運行的進程,相當于ctrl+c
9:sigkill:殺死一個進程
15:sigterm:終止進程,容許進程可以完成當前工作。
19:sigstop:停止
18:sig
命令:
1、kill -信號 pid
[root@localhost ~]# kill -9 9761
[root@localhost ~]# kill -sigkill 2119
2、killall -信號 進程名
kill是按照pid進行查找并按照信號要求做相應的處理,而killall是按照進程名進行查找并處理相關進程。
3、killall5 -信號?
對所有相關進程有效
4、調整進程nice值
nice -n # command ?默認優先級是120
renice # pid 對正在運行的進程調整其nice數值
5、作業控制
前臺送往后臺可以使用ctrl+z,但屬于停止狀態,后臺調到前臺使用fg %作業號碼
+:下一次后臺要運行的作業
-:是在+作業運行完再運行的作業。
bg %作業號碼 :讓其在后臺運行。
啟動時,讓作業直接在后臺運行:command &
用戶退出后繼續運行作業:nohup command &
終止作業:
kill %作業號碼
如果一個程序會產生多個進程,那么快速殺死多個進程的方法:
? ? 1、killall,必須給出完整的進程名。
[root@node3.dtedu.com ~]# killall ha_logd
? ? 2、pkill,簡單給出進程名就可以,名稱可以不完整。
[root@node3.dtedu.com ~]# pkill -9 heartbeat
[root@node3.dtedu.com ~]# /sbin/service: line 66:? 2291 Killed? ? ? ? ? ? ? ? ? env -i PATH="$PATH" TERM="$TERM" "${SERVICEDIR}/${SERVICE}" ${OPTIONS}
[1]+? Exit 137? ? ? ? ? ? ? ? service heartbeat stop
? ? 3、正則表達式殺死多進程。
[root@node3.dtedu.com ~]# kill -9 `pgrep crond`
5.1screen
當我們在運行一個程序需要很長時間的時候,可以使用screen,它的特點是用戶退出后程序繼續運行,并且可以切換到原來窗口中再次查看運行情況。
這里說一下detach(分離、斷開),表示用戶離開當前shell窗口,并將其放到后臺繼續執行。并通過screen -r重新登錄(attach,附件、連接物)繼續后面的操作。
下面實例終端中的
創建一個新的shell窗口,建議取一個名字,8506是進程號,可以通過kill殺死它。也可以使用簡便方法直接在screen后面跟shell命令,比如:screen -r test vi ./gongbing.txt
[root@localhost ~]# screen -ls
There are screens on:
8334.pts-0.localhost(Detached)
8506.gong(Detached)#從shell窗口分離出來了,可以重新登錄。
8580.cpfrom56(Attached)#表示此shell窗口并沒有被分離出來,使用 screen -d 8506解決。
3 Sockets in /var/run/screen/S-root.
[root@localhost ~]# screen -S cpfrom56創建一個新的shell窗口
[root@localhost ~]# ps -axu |grep 8506
Warning: bad syntax, perhaps a bogus '-'? See /usr/share/doc/procps-3.2.8/FAQ
root ? ? ? 8506? 0.0? 0.1 118776? 1556 ?? ? ? ? Ss ? 16:38 ? 0:00 SCREEN -S gong
查看運行中的screen程序screen-ls
BingGongtekiMacBook-Pro:~ binggong$ screen -ls
There is a screen on:
1396.ttys000.BingGongtekiMacBook-Pro(Detached)
1 Socket in /var/folders/dw/wp5cbg3j121_1lvp89533qlr0000gn/T/.screen.
進入某一個screen程序screen-rid
BingGongtekiMacBook-Pro:~ binggong$ screen -r 1396
[screen is terminating]
一個shell窗口中創建多個窗口可以使用ctrl+a+n的方法,切換窗口使用ctrl+a+p,從當前子shell中分離出來ctrl+a+d。
任務完成,退出操作,exit。
shell窗口屏幕共享給其他用戶,其他用戶遠程登錄服務器后通過screen -ls查看想要共享的shell窗口,通過screen -x pid來實現共享同一個shell窗口,方便做演示使用。
screen命令詳解:http://www.cnblogs.com/mchina/archive/2013/01/30/2880680.html
轉載于:https://blog.51cto.com/137783/1916974
總結
以上是生活随笔為你收集整理的七、Linux脚本进阶和进程管理的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 为部署ASP.NET Core准备:使用
- 下一篇: 最快捷地开始git