uptime
uptime命令顯示了load avg,它其實是讀取的/proc/uptime文件:
- /proc/uptime 文件
cat /proc/uptime
9592411.58 9566042.33
第一個是系統(tǒng)啟動了多久(單位s)阶剑,第二個意思是系統(tǒng)啟動以來洪添,cpu idle花費的時間(單位s)拥褂。多核機器上赁咙,第二個可能大于第一個镇匀,因為他是每個核心idle的總和照藻。
怎么才能知道uptime 真的是讀取這個文件呢?想辦法查看一下汗侵,這里可以用strace :
[root@localhost ~]# strace uptime 2>&1 | grep open
open("/proc/uptime", O_RDONLY) = 3
open("/var/run/utmp", O_RDONLY|O_CLOEXEC) = 4
open("/proc/loadavg", O_RDONLY) = 4
strace 命令在stderr上打印了uptime的系統(tǒng)調(diào)用情況幸缕,在stdout上打印命令的原始輸出。strace -e open uptime
可以起到和grep open
相同的作用晰韵。uptime只是格式化輸出了/proc的內(nèi)容发乔。如果是腳本里想要uptime值,自己讀取/proc/uptime或許更方便一些宫屠。
Load average
[root@localhost ~]# cat /proc/loadavg
0.00 0.01 0.05 2/374 40656
前三列沒什么好說的列疗,第四列是當前有多少個進程,和多少個進程處于running或者runable浪蹂,最后一列是最新的被分配的pid抵栈。running的意思是,當前進程正在物理cpu上運行坤次;runable的意思是古劲,它在等系統(tǒng)給他分配cpu時間片。
[root@localhost ~]# sleep 10 &
[1] 40674
[root@localhost ~]# sleep 10 &
[2] 40675
[root@localhost ~]# sleep 10 &
[3] 40676
[root@localhost ~]# cat /proc/loadavg
0.00 0.01 0.05 2/375 40677
可以看到缰猴,每運行一次产艾,pid就+1,cat /proc/loadavg
最后一列值可以證明滑绒。
證明第四列是當前正在運行的進程數(shù):
[root@localhost ~]# cat /proc/loadavg
0.05 0.04 0.05 2/374 40717
當前有兩個進程在運行(其中一個是當前的cat闷堡,另一個是vmware的vm-tool進程)
[root@localhost ~]# cat /dev/urandom > /dev/null &
[1] 40718
[root@localhost ~]# cat /proc/loadavg
0.09 0.04 0.05 3/375 40719
創(chuàng)建一個無意義,但不斷運行的進程(隨機生產(chǎn)些數(shù)據(jù)疑故,然后寫入/dev/null)杠览,第四列 正在運行的進程數(shù)+1(另外兩個運行中的進程和上面同理)。
load數(shù)量指進程狀態(tài)處在 :正在運行纵势、等待運行踱阿、和不可中斷(后面對這個狀態(tài)做解釋)的進程數(shù)。load avg就是過去1min钦铁,5min软舌,15min load數(shù)量的平均數(shù),但這個解析是簡化版本牛曹,其實并不太對佛点。直接引用維基百科上的解釋:
Mathematically speaking, all three values always average all the system load since the system started up. They all decay exponentially, but they decay at different speed. Hence, the 1-minute load average will add up 63% of the load from last minute, plus 37% of the load since start up excluding the last minute. Therefore, it's not technically accurate that the 1-minute load average only includes the last 60 seconds activity (since it still includes 37% activity from the past), but that includes mostly the last minute.
關(guān)于不可中斷狀態(tài):
進程 struct task_struct
的 state 字段為TASK_UNINTERRUPTIBLE,進程陷入了不能被中斷的阻塞操作,無視信號黎比。 What is an uninterruptable process?
http://stackoverflow.com/questions/223644/what-is-an-uninterruptable-process
另外一個關(guān)于不可中斷狀態(tài)的解釋還不錯:https://yq.aliyun.com/articles/8902
內(nèi)核的某些處理流程是不能被打斷的恋脚。如果響應(yīng)異步信號腺办,程序的執(zhí)行流程中就會被插入一段用于處理異步信號的流程(這個插入的流程可能只存在于內(nèi)核態(tài),也可能延伸到用戶態(tài))糟描,于是原有的流程就被中斷了
如果是單核cpu的話怀喉,loadavg是1(同一時間運行一個進程),就說明cpu利用率是100%船响。如果是雙核cpu躬拢,loadavg為2(同一時間運行兩個進程)說明cpu利用率是100%。htop左上角和nproc命令可以看系是幾核cpu见间。
load數(shù)量包括了不可中斷的進程數(shù)聊闯,但是處于這個狀態(tài)的進程并不怎么影響cpu運行(可以認為不使用cpu時間)。所以從loadavg推斷cpu使用率不太準米诉,這也能解釋一些為什么load很高菱蔬,但是實際cpu使用率不高。
mpstat可以查看瞬時cpu使用情況史侣,要安裝sysstat(這是個牛逼的工具)拴泌。
[root@localhost ~]# yum install sysstat -y
[root@localhost ~]# mpstat 1
Linux 3.10.0-327.el7.x86_64 (localhost.virthost) 02/26/17 _x86_64_ (1 CPU)
17:38:41 CPU %usr %nice %sys %iowait %irq %soft %steal %guest %gnice %idle
17:38:42 all 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00
17:38:43 all 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00
^C
Average: all 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00
進程
htop默認顯示用戶進程和用戶線程。
shift+H打開關(guān)閉用戶線程
shift+K打開關(guān)閉內(nèi)核線程
F5顯示進程繼承關(guān)系(類似ps -f)
/proc/<pid>/{pwd,exe,cmdline} 里包含了進程當前工作目錄的鏈接惊橱,可執(zhí)行程序的鏈接和命令行蚪腐。可以通過讀取procfs里的內(nèi)容税朴,從內(nèi)核獲取信息回季。
/proc/<pid>/status 包含當前進程的許多信息(內(nèi)存分配情況,父進程id等)正林,uid指明了當前進程所屬用戶:
[root@localhost htop]# cat /proc/47937/status | grep Uid
Uid: 0 0 0 0
id <uid>
命令可以找到這個用戶的相關(guān)信息泡一。其實id也是讀取/etc/passwd和/etc/group文件獲取用戶信息:
[root@localhost]# strace -e open id 0
...
open("/etc/nsswitch.conf", O_RDONLY|O_CLOEXEC) = 3
open("/lib64/libnss_files.so.2", O_RDONLY|O_CLOEXEC) = 3
open("/etc/passwd", O_RDONLY|O_CLOEXEC) = 3
open("/etc/group", O_RDONLY|O_CLOEXEC) = 3
uid=0(root) gid=0(root) groups=0(root)
+++ exited with 0 +++
為什么會去找/etc/passwd 呢?這個是讀取了/etc/nsswitch.conf 配置觅廓。
[root@localhost htop]# cat /etc/nsswitch.conf
...
passwd: files sss
shadow: files sss
group: files sss
...
關(guān)于這個配置文件瘾杭,可以參考這里:<http://www.cnblogs.com/cute/archive/2012/05/17/2506342.html>,總之就是/lib64/libnss_files.so 加載了這個文件哪亿,其他的一系列的name service和這個文件有關(guān)(比如dns),還可以配置成從ldap中獲取用戶名密碼贤笆。
unix用戶的密碼保存在/etc/shadow:
[root@localhost]# cat /etc/shadow
root:$6$eS1H0Kk/$MPOOjZyuhc14tzBl.2O2VoLoXxkirzIdKKw41tP/cEjfEPe58VcQB3LLlGoJzuHRrE.WIjii9nalKWl/GJMoR/:17153:0:99999:7:::
第二列開頭的$6$表示加密算法是sha512蝇棉,后面緊接著是鹽和鹽+密碼的hash。
用戶運行可執(zhí)行文件時芥永,進程所屬用戶一般是當前用戶自己篡殷,而不是可執(zhí)行文件本身的屬主(這點應(yīng)該很好理解)。
使用sudo -u 運行程序可以切換進程屬主埋涧。sudo權(quán)限在 /etc/sudoers
配置板辽,最好使用visudo編輯配置文件奇瘦,它會對文件格式做驗證。
/etc/passwd是非常敏感的文件劲弦,passwd在普通用戶權(quán)限下運行耳标,也能更改密碼,說明passwd肯定是以root身份運行的邑跪,否則它沒發(fā)修改passwd文件次坡。當二進制程序有x權(quán)限后,可以設(shè)置setuid權(quán)限:
sudo chmod u+s /usr/bin/passwd
[root@localhost]# ls -l /usr/bin/passwd
-rwsr-xr-x. 1 root root 27832 Jun 10 2014 /usr/bin/passwd
這樣画畅,二進制文件運行時砸琅,進程屬主就是二進制文件的屬主。
其他的特殊權(quán)限還有sticky bit和setgid轴踱。下面的命令可以找到權(quán)限類似passwd這樣的命令:
[root@localhost]# find /usr/bin -user root -perm -u+s
/usr/bin/chage
/usr/bin/gpasswd
/usr/bin/newgrp
/usr/bin/chfn
/usr/bin/chsh
/usr/bin/su
/usr/bin/sudo
/usr/bin/mount
/usr/bin/umount
/usr/bin/staprun
/usr/bin/crontab
/usr/bin/pkexec
/usr/bin/passwd
進程狀態(tài)
- R 在運行隊列里
- S 可中斷的休眠(等待事件發(fā)生)
- D 不可中斷的休眠症脂,發(fā)生頁面錯誤時,發(fā)生的IO不可以被中斷淫僻,進程此時不能處理信號诱篷,處理信號可能會造成另外一個頁面錯誤。如果有太多進程處于這個狀態(tài)嘁傀,意味著有可能大量進程發(fā)生頁面錯誤兴蒸,也許應(yīng)該看下swap。
- Z 僵尸狀態(tài)细办,子進程退出后橙凳,相關(guān)的資源已經(jīng)釋放,父進程應(yīng)該在收到SIGCHL信號后D收尸笑撞,不應(yīng)該把子進程隨便亂扔岛啸。
- T 被任務(wù)控制信號停止,ctrl+z終止后臺進程可以看到這種狀態(tài)茴肥。
- t 被debugger停止(調(diào)試)坚踩,gdb -p <pid> attach的進程,可以看到這個狀態(tài)瓤狐。
- X 應(yīng)該永遠看不見
F9 htop 發(fā)送信號快捷鍵
可以制造一個處于uninterruptible狀態(tài)的進程瞬铸。使用NFS掛在遠程目錄的時候,如果遠程目錄不存在础锐,進程就會被掛起嗓节。我們使用google的DNS 8.8.8.8 試試,因為它沒有打開NFS:
[root@localhost ~]# mount 8.8.8.8:/tmp /tmp &
[1] 48642
[root@localhost ~]# ps aux | grep mount
root 48642 0.0 0.0 125628 924 pts/1 S 22:03 0:00 mount 8.8.8.8:/tmp /tmp
root 48643 0.0 0.1 42468 1608 pts/1 D 22:03 0:00 /sbin/mount.nfs 8.8.8.8:/tmp /tmp -o rw
root 48645 0.0 0.0 112616 700 pts/1 R+ 22:03 0:00 grep --color=auto mount
使用strace看看它到底在哪個調(diào)用上掛起了:
[root@localhost ~]# sudo strace /sbin/mount.nfs 8.8.8.8:/tmp /tmp -o rw
...
mount("8.8.8.8:/tmp", "/tmp", "nfs", 0, "vers=4,addr=8.8.8.8,clientaddr=1"...
進程運行的時間
linux的時間片大約在幾毫秒(搞清楚linux上時間片到底多長也挺有意思的)皆警。loadavg在單核機器上小于1拦宣,意味這cpu在過去一段時間什么事情都沒做。
進程優(yōu)先級
- NI 用戶空間優(yōu)先級,最低-20到最高19鸵隧。經(jīng)驗是升一級優(yōu)先級通吵衤蓿可以獲得10%的更多cpu時間。
- PRI 內(nèi)核空間優(yōu)先級豆瘫,0-139珊蟀。0-99是實時優(yōu)先級,100-139才是給用戶進程用的靡羡,這映射到用戶優(yōu)先級的-20到19系洛。
內(nèi)存
編寫用戶空間的程序員或者程序,會感覺自己的程序擁有全部內(nèi)存略步,這是幻覺描扯。
用戶態(tài)程序不會直接訪問物理內(nèi)存,只能訪問虛擬內(nèi)存空間趟薄,內(nèi)核會把虛擬地址映射到物理內(nèi)存或者磁盤上绽诚。
htop/top內(nèi)存的含義:
- VIRT/VSZ 虛擬內(nèi)存,包括二進制的代碼杭煎,數(shù)據(jù)恩够,共享庫,換出的頁羡铲,映射了但是還沒使用的頁蜂桶。
- RES/RSS 進程實際在物理內(nèi)存中的空間,不包括換出的內(nèi)存也切,但是包括和其他進程共享的扑媚。
- SHR 共享的內(nèi)存
htop/top內(nèi)存使用率是指RES/RSS內(nèi)存占總物理內(nèi)存的百分比。