top/htop內容的含義

uptime

uptime命令顯示了load avg,它其實是讀取的/proc/uptime文件:

  • /proc/uptime 文件
cat /proc/uptime
9592411.58 9566042.33

第一個是系統啟動了多久(單位s),第二個意思是系統啟動以來,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的系統調用情況,在stdout上打印命令的原始輸出。strace -e open uptime 可以起到和grep open相同的作用。uptime只是格式化輸出了/proc的內容。如果是腳本里想要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的意思是,它在等系統給他分配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最后一列值可以證明。
證明第四列是當前正在運行的進程數:

[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

創建一個無意義,但不斷運行的進程(隨機生產些數據,然后寫入/dev/null),第四列 正在運行的進程數+1(另外兩個運行中的進程和上面同理)。
load數量指進程狀態處在 :正在運行、等待運行、和不可中斷(后面對這個狀態做解釋)的進程數。load avg就是過去1min,5min,15min load數量的平均數,但這個解析是簡化版本,其實并不太對。直接引用維基百科上的解釋:

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.

關于不可中斷狀態:

進程 struct task_struct
state 字段為TASK_UNINTERRUPTIBLE,進程陷入了不能被中斷的阻塞操作,無視信號。 What is an uninterruptable process?
http://stackoverflow.com/questions/223644/what-is-an-uninterruptable-process

另外一個關于不可中斷狀態的解釋還不錯:https://yq.aliyun.com/articles/8902

內核的某些處理流程是不能被打斷的。如果響應異步信號,程序的執行流程中就會被插入一段用于處理異步信號的流程(這個插入的流程可能只存在于內核態,也可能延伸到用戶態),于是原有的流程就被中斷了

如果是單核cpu的話,loadavg是1(同一時間運行一個進程),就說明cpu利用率是100%。如果是雙核cpu,loadavg為2(同一時間運行兩個進程)說明cpu利用率是100%。htop左上角和nproc命令可以看系是幾核cpu。
load數量包括了不可中斷的進程數,但是處于這個狀態的進程并不怎么影響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打開關閉用戶線程
shift+K打開關閉內核線程
F5顯示進程繼承關系(類似ps -f)

/proc/<pid>/{pwd,exe,cmdline} 里包含了進程當前工作目錄的鏈接,可執行程序的鏈接和命令行。可以通過讀取procfs里的內容,從內核獲取信息。
/proc/<pid>/status 包含當前進程的許多信息(內存分配情況,父進程id等),uid指明了當前進程所屬用戶:

[root@localhost htop]# cat /proc/47937/status | grep Uid
Uid: 0 0 0 0

id <uid>命令可以找到這個用戶的相關信息。其實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
...

關于這個配置文件,可以參考這里:<http://www.cnblogs.com/cute/archive/2012/05/17/2506342.html>,總之就是/lib64/libnss_files.so 加載了這個文件,其他的一系列的name service和這個文件有關(比如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。
用戶運行可執行文件時,進程所屬用戶一般是當前用戶自己,而不是可執行文件本身的屬主(這點應該很好理解)。
使用sudo -u 運行程序可以切換進程屬主。sudo權限在 /etc/sudoers配置,最好使用visudo編輯配置文件,它會對文件格式做驗證。
/etc/passwd是非常敏感的文件,passwd在普通用戶權限下運行,也能更改密碼,說明passwd肯定是以root身份運行的,否則它沒發修改passwd文件。當二進制程序有x權限后,可以設置setuid權限:

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

這樣,二進制文件運行時,進程屬主就是二進制文件的屬主。
其他的特殊權限還有sticky bit和setgid。下面的命令可以找到權限類似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

進程狀態

  • R 在運行隊列里
  • S 可中斷的休眠(等待事件發生)
  • D 不可中斷的休眠,發生頁面錯誤時,發生的IO不可以被中斷,進程此時不能處理信號,處理信號可能會造成另外一個頁面錯誤。如果有太多進程處于這個狀態,意味著有可能大量進程發生頁面錯誤,也許應該看下swap。
  • Z 僵尸狀態,子進程退出后,相關的資源已經釋放,父進程應該在收到SIGCHL信號后D收尸,不應該把子進程隨便亂扔。
  • T 被任務控制信號停止,ctrl+z終止后臺進程可以看到這種狀態。
  • t 被debugger停止(調試),gdb -p <pid> attach的進程,可以看到這個狀態。
  • X 應該永遠看不見

F9 htop 發送信號快捷鍵

可以制造一個處于uninterruptible狀態的進程。使用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看看它到底在哪個調用上掛起了:

[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在過去一段時間什么事情都沒做。

進程優先級

  • NI 用戶空間優先級,最低-20到最高19。經驗是升一級優先級通常可以獲得10%的更多cpu時間。
  • PRI 內核空間優先級,0-139。0-99是實時優先級,100-139才是給用戶進程用的,這映射到用戶優先級的-20到19。

內存

編寫用戶空間的程序員或者程序,會感覺自己的程序擁有全部內存,這是幻覺。
用戶態程序不會直接訪問物理內存,只能訪問虛擬內存空間,內核會把虛擬地址映射到物理內存或者磁盤上。
htop/top內存的含義:

  • VIRT/VSZ 虛擬內存,包括二進制的代碼,數據,共享庫,換出的頁,映射了但是還沒使用的頁。
  • RES/RSS 進程實際在物理內存中的空間,不包括換出的內存,但是包括和其他進程共享的。
  • SHR 共享的內存
    htop/top內存使用率是指RES/RSS內存占總物理內存的百分比。
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • Ubuntu的發音 Ubuntu,源于非洲祖魯人和科薩人的語言,發作 oo-boon-too 的音。了解發音是有意...
    螢火蟲de夢閱讀 99,466評論 9 467
  • linux資料總章2.1 1.0寫的不好抱歉 但是2.0已經改了很多 但是錯誤還是無法避免 以后資料會慢慢更新 大...
    數據革命閱讀 12,203評論 2 33
  • 如果你想知道你的服務器正在做干什么,你就需要了解一些基本的命令,一旦你精通了這些命令,那你就是一個專業的 Linu...
    七寸知架構閱讀 10,917評論 1 71
  • 進程相關概念系統進程管理工具任務計劃 一、進程相關概念 定義:進程(Process)是運行中的程序的一個副本,是被...
    哈嘍別樣閱讀 590評論 0 0
  • —直到和你做了多年朋友,才明白我的眼淚不是為你而流,也為別人而流。 人生若只如初見 胡靜記得高一軍訓的那天晚上,那...
    若雨小姑娘閱讀 538評論 13 17