跟運維學 Linux - 03

来源:https://www.cnblogs.com/pengjiali/archive/2023/08/03/17578893.html
-Advertisement-
Play Games

## 許可權機制和性能指標 前面我們學完了`操作文件`和`用戶`相關知識,本篇學習`許可權`和`性能`相關知識。 ### 文件的屬性看起 看 linux 的許可權,先從文件的屬性看起 ls -l 加 `-d` 是只看這個文件夾: ```javascript pjl@pjl-pc:~$ sudo ls -l ...


許可權機制和性能指標

前面我們學完了操作文件用戶相關知識,本篇學習許可權性能相關知識。

文件的屬性看起

看 linux 的許可權,先從文件的屬性看起

ls -l 加 -d 是只看這個文件夾:

pjl@pjl-pc:~$ sudo ls -ld /root
drwx------ 8 root root 4096 7月  18 16:20 /root

最左側的 d 表示目錄,這個前面已經說過,後面的又是什麼?我們兩部分來講:rwx------root root

屬主和屬組

root root,第一個 root 表示這個文件夾是 root 用戶,後一個 root 表示這個文件夾是 root 組的。

專業的叫法,前者叫做文件夾的屬主,後者叫做文件夾的屬組

我們再來看一個:

pjl@pjl-pc:~$ ls -ld /home/test19
drwxr-xr-x 2 test19 test19 4096 7月  18 15:32 /home/test19

這裡說明 /home/test19 文件夾的主人是 test19 用戶,test19 組成員也是這個文件夾的主人。

既然 root 用戶和 root 組成員是 /root 文件夾的主人,是否就可以對其為所欲為

許可權位

明白了屬主和屬組,如何看一個一個的文件以及文件夾的許可權?

我們把 rwx------ 拆成三部分來看:rwx------

root 用戶的許可權對應第一部分:rwx。可讀,可寫,可執行。

root 組成員的許可權對應第二部分:---。不可讀、不可寫、不可執行

許可權位由三部分組成:讀許可權(r/-) + 寫許可權(w/-) + 執行許可權(x/-)。

位許可權和普通文件的關係

普通文件和文件夾的許可權位,代表的意思不一樣。

先看普通文件:

pjl@pjl-pc:~/linux-test$ ls -l
總用量 4
-rwxrw-r-- 1 pjl pjl 6 7月  19 17:14 a.txt

pjl 用戶對應的許可權是可讀可寫可執行(rwx)。

對於 pjl 組成員的許可權是可讀可寫不可執行(rw-)。

對於普通文件,可讀就是能讀取(例如 cat、head)文件內容:

pjl@pjl-pc:~/linux-test$ cat a.txt
apple

對於普通文件,可寫許可權就是可以通過編輯保存。如果沒有寫許可權,vim 不讓你保存。

執行許可權,後續講腳本的時候再說,簡單理解:是否可以運行腳本。

// 創建一個腳本
pjl@pjl-pc:~/linux-test$ ls -l
-rw-rw-r-- 1 pjl pjl 26 7月  19 17:40 a.sh
// 沒有執行許可權
pjl@pjl-pc:~/linux-test$ ./a.sh
-bash: ./a.sh: 許可權不夠
// 增加執行許可權
pjl@pjl-pc:~/linux-test$ chmod u+x a.sh
pjl@pjl-pc:~/linux-test$ ls -l
-rwxrw-r-- 1 pjl pjl 26 7月  19 17:40 a.sh
// 能執行了
pjl@pjl-pc:~/linux-test$ ./a.sh
hello
位許可權和文件夾的關係

以這個文件夾為例:

pjl@pjl-pc:~/linux-test$ ls -ld dir1
d-wxrwxr-x 2 pjl pjl 4096 7月  19 18:38 dir1

文件夾如果有讀許可權,才能使用 ls:

pjl@pjl-pc:~/linux-test$ ls dir1
ls: 無法打開目錄'dir1': 許可權不夠

文件夾寫許可權,表示我們可以改變這個文件夾下的內容。比如創建文件、刪除文件、創建子文件夾。

pjl@pjl-pc:~/linux-test$ touch dir1/b.txt
pjl@pjl-pc:~/linux-test$ ls dir1
ls: 無法打開目錄'dir1': 許可權不夠

文件夾執行許可權,表示能不能進入這個文件夾。最直接就是 cd 能不能用:

pjl@pjl-pc:~/linux-test$ cd dir1
pjl@pjl-pc:~/linux-test/dir1$ ls
ls: 無法打開目錄'.': 許可權不夠
// 雖然文件夾沒有讀許可權,但可以查看裡面的文件內容
pjl@pjl-pc:~/linux-test/dir1$ cat b.txt
i am b.txt
其他用戶許可權

rwx------ 的最後三位(---)表示其他用戶的許可權。也就是屬主和屬組以外的用戶。

例如 /root 文件夾對於其他用戶的許可權是---:不可讀、不可寫、不可執行

drwx------ 12 root root 4096 6月  14 09:35 /root

我們創建用戶 user1 去讀、寫和執行:

// 不可讀
user1@pjl-pc:~$ ls /root
ls: 無法打開目錄'/root': 許可權不夠
// 不可執行
user1@pjl-pc:~$ cd /root
-bash: cd: /root: 許可權不夠
// 不可寫
user1@pjl-pc:~$ touch /root/a.txt
touch: 無法創建 '/root/a.txt': 許可權不夠
user1@pjl-pc:~$

修改許可權

如何修改許可權,用一個小任務來舉例說明。

linux 下有一個用戶 user1,他的家目錄是 /home/user1,不過目前他無法進入自己的家目錄。

pjl@pjl-pc:~/linux-test$ su - user1
輸入密碼
su: warning: cannot change directory to /home/user1: 許可權不夠
-bash: /home/user1/.bash_profile: 許可權不夠
user1@pjl-pc:/home/pjl/linux-test$ ls /home/user1
ls: 無法打開目錄'/home/user1': 許可權不夠

作為系統管理員,我們要查看原因:

pjl@pjl-pc:~/linux-test$ ls -ld /home/user1
d--------- 4 root root 4096 7月  19 19:01 /home/user1

這裡有兩個問題:

  • 屬主和屬組不應該是 root,而應該是用戶自己
  • 位許可權都是 -

使用 chown 改變屬主和數組:

pjl@pjl-pc:~/linux-test$ sudo chown -R user1:user1 /home/user1
pjl@pjl-pc:~/linux-test$ ls -ld /home/user1
d--------- 4 user1 user1 4096 7月  19 19:01 /home/user1

現在還是進不去,需要修改位許可權。

使用 chmod 修改位許可權:

// u=rwx 給屬主位許可權設置成 rwx
pjl@pjl-pc:~/linux-test$ sudo chmod u=rwx /home/user1
pjl@pjl-pc:~/linux-test$ ls -ld /home/user1
drwx------ 4 user1 user1 4096 7月  19 19:01 /home/user1
// g=rx 給屬組位許可權位設置成 rx
pjl@pjl-pc:~/linux-test$ sudo chmod g=rx /home/user1
pjl@pjl-pc:~/linux-test$ ls -ld /home/user1
drwxr-x--- 4 user1 user1 4096 7月  19 19:01 /home/user1

Tip:用數字設置許可權位更方便

// 同時設置屬主、屬組和其他用戶許可權
// 7 = r(4) + w(2) + x(1)
// 7 = r(4) + w(2) + x(1)
// 4 = r(4)
pjl@pjl-pc:~/linux-test$ sudo chmod 774 /home/user1
pjl@pjl-pc:~/linux-test$ ls -ld /home/user1
drwxrwxr-- 4 user1 user1 4096 7月  19 19:01 /home/user1

現在就正常了:

pjl@pjl-pc:~/linux-test$ su - user1
輸入密碼
user1@pjl-pc:~$ pwd
/home/user1
user1@pjl-pc:~$ ls -ld /home/user1
drwxrwxr-- 4 user1 user1 4096 7月  19 19:01 /home/user1

性能指標

作為 linux 工程師,會聽到主管:現在伺服器夠用嗎,要在買幾台嗎?

先登錄一遍伺服器,查看當前容量和性能,在做決定。

在 linux 下如何查看性能指標?趕快學一下!

磁碟

先執行命令 df(disk free 的縮寫)查看磁碟使用情況:

pjl@pjl-pc:~/linux-test$ df -h
文件系統        容量  已用  可用 已用% 掛載點
udev            3.8G  4.0K  3.8G    1% /dev
tmpfs           790M  1.4M  788M    1% /run
/dev/sda3        98G   23G   71G   25% /
/dev/sda2       2.0G  319M  1.5G   18% /boot
/dev/sda1       511M   11M  501M    3% /boot/efi
/dev/sda5       708G   55G  618G    9% /data

感覺看不太懂!

我們最關心的是還剩多少空間,我們可以關註可用已用%這2列。

每一行就是硬碟上各個分區的使用情況。

什麼是分區,和windows的C盤、D盤有什麼不同?帶著這些疑問我們進入下一節。

硬碟和分區

以我們熟悉的 windows 為例,一塊硬碟分成了兩個分區(01、02),通常我們使用滑鼠點擊圖標(C盤)進入分區01,或者用滑鼠點擊圖標(D盤)進入分區02

在 linux 中,一塊磁碟也分成兩個分區(01、02),不同的是沒有圖標(C盤、D盤),也沒有滑鼠,而是通過目錄進入對應的分區。

我們用命令 fdisk -l(全稱是 fixed disk) 查看有幾塊硬碟,幾個分區:

pjl@pjl-pc:~/linux-test$ sudo fdisk -l
Disk /dev/sda:931.53 GiB,1000204886016 位元組,1953525168 個扇區
Disk model: WDC WD10EZEX-08W
單元:扇區 / 1 * 512 = 512 位元組
扇區大小(邏輯/物理):512 位元組 / 4096 位元組
I/O 大小(最小/最佳):4096 位元組 / 4096 位元組
磁碟標簽類型:gpt
磁碟標識符:ADCE9537-745A-4B58-94AD-E260DD688EF6

設備             起點       末尾       扇區   大小 類型
/dev/sda1        2048    1050623    1048576   512M EFI 系統
/dev/sda2     1050624    5244927    4194304     2G Linux 文件系統
/dev/sda3     5244928  214960127  209715200   100G Linux 文件系統
/dev/sda4   214960128  424675327  209715200   100G Linux 文件系統
/dev/sda5   424675328 1934133247 1509457920 719.8G Linux 文件系統
/dev/sda6  1934133248 1953523711   19390464   9.3G Linux swap

最上方的 /dev/sda 表一塊磁碟。前面我們說過“linux 中一切都是文件”。在 linux 中,用來表示硬碟和分區(或者說設備)的文件,統一放在 /dev 目錄中。

sda 代表什麼?將其拆開 sd 和 a。sd 表示 SATA 介面的硬碟,而 a 表示第一塊硬碟,如果有更多的硬碟,就順序往下排列:b、c、d...

Tip: 一般個人電腦,硬碟介面分兩種,老式的 ide硬碟 和新的 SATA硬碟,現在基本上都是 SATA。

磁碟上的分區就用數字表示,例如sda硬碟的分區:/dev/sda1、/dev/sda2...

結合 fdisk 和 df

現在我們結合 fdisk 和 df 來查看:

pjl@pjl-pc:~/linux-test$ sudo fdisk -l
輸入密碼
Disk /dev/sda:931.53 GiB,1000204886016 位元組,1953525168 個扇區
Disk model: WDC WD10EZEX-08W
單元:扇區 / 1 * 512 = 512 位元組
扇區大小(邏輯/物理):512 位元組 / 4096 位元組
I/O 大小(最小/最佳):4096 位元組 / 4096 位元組
磁碟標簽類型:gpt
磁碟標識符:ADCE9537-745A-4B58-94AD-E260DD688EF6

設備             起點       末尾       扇區   大小 類型
/dev/sda1        2048    1050623    1048576   512M EFI 系統
/dev/sda2     1050624    5244927    4194304     2G Linux 文件系統
/dev/sda3     5244928  214960127  209715200   100G Linux 文件系統
/dev/sda4   214960128  424675327  209715200   100G Linux 文件系統
/dev/sda5   424675328 1934133247 1509457920 719.8G Linux 文件系統
/dev/sda6  1934133248 1953523711   19390464   9.3G Linux swap

df 最左側是分區,最右側是分區的入口:

pjl@pjl-pc:~/linux-test$ df -h
文件系統        容量  已用  可用 已用% 掛載點
udev            3.8G  4.0K  3.8G    1% /dev
tmpfs           790M  1.4M  788M    1% /run
/dev/sda3        98G   23G   71G   25% /
/dev/sda2       2.0G  319M  1.5G   18% /boot
/dev/sda1       511M   11M  501M    3% /boot/efi
/dev/sda5       708G   55G  618G    9% /data
tmpfs           3.9G  8.0K  3.9G    1% /dev/shm
tmpfs           5.0M  4.0K  5.0M    1% /run/lock
tmpfs           3.9G     0  3.9G    0% /sys/fs/cgroup
tmpfs           790M   48K  789M    1% /run/user/1000

比如分區 /dev/sda3 入口是 /。前面我們已經知道 / 是根目錄。

比如 /dev/sda5 入口是 /data。

現在我們做一個試驗,來驗證分區的入口。

現在 /dev/sda5 已用容量是 55590 M:

// -m 表示M
pjl@pjl-pc:/data$  df -m |egrep 'sda5|可用'
文件系統        1M-塊  已用   可用 已用% 掛載點
/dev/sda5      724447 55590 631989    9% /data

我們在 /data 目錄中使用 dd 生成一個200M的文件:

// /dev/zero 是一個特殊的文件,當你讀它的時候,它會提供無限的空字元
pjl@pjl-pc:/data$ dd if=/dev/zero of=swapfile bs=1M count=200
記錄了200+0 的讀入
記錄了200+0 的寫出
209715200 bytes (210 MB, 200 MiB) copied, 0.224172 s, 936 MB/s
pjl@pjl-pc:/data$ ls
home  lost+found  root  swapfile  usershare

現在 /dev/sda5 已用容量比之前正好多 200M。

pjl@pjl-pc:/data$ df -m |egrep 'sda5|可用'
文件系統        1M-塊  已用   可用 已用% 掛載點
/dev/sda5      724447 55790 631789    9% /data

tmpfs 又是什麼,帶著疑問我們進入下一節。

記憶體

快速理解記憶體

平時我們玩電腦,無非就是聽音樂、玩游戲、看電影,這些數據平時統統放在硬碟中,因為硬碟空間大。以玩下象棋為例,電腦會有如下一個大致流程:

  1. cpu 向硬碟發送命令,找到所需的游戲數據
  2. 游戲數據從硬碟調入到記憶體中
  3. 每玩一步都在記憶體中。cpu 大多數也只和記憶體互動數據,因為記憶體比硬碟快得多。
  4. 游戲結束,將結果保存到磁碟中,等待下次在玩。

Tip:硬碟容量最大,存放的都是暫時不用的;記憶體通過不能永久存儲數據,斷電就清空了;電腦速度:cpu > 記憶體 > 硬碟;如果 cpu 直接和硬碟交互,就得苦苦等候。

free 查看記憶體指標

既然記憶體那麼重要,我們最關心的是還有多少可用記憶體。

命令很簡單,使用 free 查看:

pjl@pjl-pc:/data$ free -h
              總計         已用        空閑      共用    緩衝/緩存    可用
記憶體:       7.7Gi       1.6Gi       1.3Gi        10Mi       4.8Gi       5.9Gi
交換:       9.2Gi          0B       9.2Gi

我們看第一行,總共有 7.7 G,已使用 1.6G。

Tip:共用,幾乎無實際用處。

空閑1.3G,可用5.9G,哪個才是剩餘記憶體?為了弄清楚,我們得說一下 linux 記憶體原理

free 查看記憶體的基本原理

古代打戰使用屯田制,沒有戰爭的時候,士兵就去耕田。

這裡的空閑(free)就是不打戰也不耕田計程車兵。

緩衝/緩存(cache/buffer)就是耕田計程車兵。

在君王眼中,耕田沒有打戰的優先順序高。一旦戰事來臨,空閑的和耕田的都可派出去。

可用=空閑+緩衝/緩存。所以這裡剩餘記憶體是 5.9G。

空閑很好理解,那麼緩衝/緩存代表什麼意思?請看下節。

記憶體中的 cache 高速緩存

記憶體的速度很快,但遠遠趕不上 cpu。

把 CPU 比作給災區送水的車,記憶體比作災區用桶取水的人,車出水的速度很快,災區的人用桶取水的速度卻很慢,水車不能一直在這等著災民慢慢取水,因為還得去其他災區送水。

cache 就好比蓄水池,cpu 把水快速放入蓄水池就走了,災區的人從蓄水池中慢慢取水。

就像這樣:

cpu(送水車) -> cache(蓄水池) -> 記憶體(災區取水的人)
buffer 緩衝區

buffer 緩衝區是為了提高寫硬碟的速度。

打個比方,姑娘摘蘋果要運到集市賣,如果每摘一個蘋果就放到卡車中,效率太低,所以會準備一個籮筐,先把蘋果放入籮筐,籮筐滿了在一次性放入卡車。

buffer 就是一個大籮筐,每當有大量數據要寫入硬碟時,把零碎的數據先放入 buffer。當 buffer 積累到一定程度,在一次性寫入硬碟。

cache 是為了高效的讀,buffer 為了高效的寫

現在緩衝/緩存是 4585 M:

pjl@pjl-pc:/data$ free -m
              總計         已用        空閑      共用    緩衝/緩存    可用
記憶體:        7890        1897        1407          14        4585        5778
交換:        9467           9        9458

清理緩存後是 579 M:

// 清理頁緩存、目錄項和inode緩存
pjl@pjl-pc:/data$ sudo sh -c 'echo 3 > /proc/sys/vm/drop_caches'
pjl@pjl-pc:/data$ free -m
              總計         已用        空閑      共用    緩衝/緩存    可用
記憶體:        7890        1846        5463          13         579        5856
交換:        9467           1        9466

測試失敗:打算先查看緩存,通過執行 time find /,預期緩存增加,下次在執行 time find /,所花費的的時間應該減少

CPU

這一項指標有點抽象,不像硬碟和記憶體那麼一目瞭然。

有朋友可能就會疑問:不就是一個 cpu 使用率嗎,比如現在用了80%,一個數字而已。

很遺憾,linux 沒有這樣直觀的方法來看 cpu,而是需要掌握一定的CPU使用率計算公式,才能瞭解當下 cpu 的高低。

先學什麼是進程

進程就是一個應用。

比如你使用瀏覽器是一個進程,使用QQ又是一個進程。

由於 windows 是圖形化的,所以看得比較清楚。

而在 linux 中想要看到進程,就需要一些方法。

比如我們用 ping 命令就會開啟一個進程:

pjl@pjl-pc:/data$ ping 192.168.1.110
PING 192.168.1.110 (192.168.1.110) 56(84) bytes of data.
64 bytes from 192.168.1.110: icmp_seq=1 ttl=64 time=0.028 ms
64 bytes from 192.168.1.110: icmp_seq=2 ttl=64 time=0.021 ms
64 bytes from 192.168.1.110: icmp_seq=3 ttl=64 time=0.020 ms
64 bytes from 192.168.1.110: icmp_seq=4 ttl=64 time=0.034 ms
64 bytes from 192.168.1.110: icmp_seq=5 ttl=64 time=0.032 ms
64 bytes from 192.168.1.110: icmp_seq=6 ttl=64 time=0.031 ms
64 bytes from 192.168.1.110: icmp_seq=7 ttl=64 time=0.028 ms
64 bytes from 192.168.1.110: icmp_seq=8 ttl=64 time=0.036 ms
64 bytes from 192.168.1.110: icmp_seq=9 ttl=64 time=0.034 ms
64 bytes from 192.168.1.110: icmp_seq=10 ttl=64 time=0.038 ms
...

現在這個命令行完全被這個進程占據,我們不能再輸入其他命令。這個叫前臺進程

與之對應的有後臺進程,比如:

// >> 是追加內容。這裡是將 ping 的輸出追加到 ping.log 文件中
pjl@pjl-pc:~/linux-test$ ping 192.168.1.110 >> ping.log &
[1] 486803
pjl@pjl-pc:~/linux-test$

通過 & 讀做and,把它放在命令行末尾,可以將該進程放在後臺。於是我們可以繼續敲別的命令。

這個命令是否還在執行,我們可以通過 tail -f 看到ping 進程正不停地往文件中寫數據:

pjl@pjl-pc:~/linux-test$ tail -f ping.log
64 bytes from 192.168.1.110: icmp_seq=5 ttl=64 time=0.031 ms
64 bytes from 192.168.1.110: icmp_seq=6 ttl=64 time=0.022 ms
64 bytes from 192.168.1.110: icmp_seq=7 ttl=64 time=0.031 ms
64 bytes from 192.168.1.110: icmp_seq=8 ttl=64 time=0.029 ms
64 bytes from 192.168.1.110: icmp_seq=9 ttl=64 time=0.024 ms
64 bytes from 192.168.1.110: icmp_seq=10 ttl=64 time=0.026 ms
...
ps 查看用戶自己的進程
pjl@pjl-pc:~/linux-test$ jobs
[1]+  運行中               ping 192.168.1.110 >> ping.log &

這裡看到剛纔放在後臺運行的 ping 進程。

jobs 只能看到那些用 & 放入後臺的進程,更多的後臺進程無法顯示。

接下來我們需要使用:ps(process status) 進程狀態。

直接輸入 ps 通常只會顯示兩個進程:

pjl@pjl-pc:~/linux-test$ ps
    PID TTY          TIME CMD
  56412 pts/1    00:00:00 bash
 499971 pts/1    00:00:00 ps
pjl@pjl-pc:~/linux-test$ whoami
pjl

第一個 bash,指當前用戶正在用的命令行是 bash;第二個 ps 是剛纔我們運行了 ps,所以自身產生了一瞬間的進程,也同樣顯示在這裡。

使用另一個用戶輸入 ps,雖然也是 bash 和 ps 進程,從進程號(PID)我們可以看出,每個用戶的進程是不同的。

user1@pjl-pc:~$ ps
    PID TTY          TIME CMD
 499859 pts/0    00:00:00 bash
 499878 pts/0    00:00:00 ps
user1@pjl-pc:~$ whoami
user1
ps 查看全局進程

通過 ps -ef 查看操作系統所有的進程:

pjl@pjl-pc:~/linux-test$ ps -ef | head
UID          PID    PPID  C STIME TTY          TIME CMD
root           1       0  0 7月19 ?       00:00:19 /sbin/init splash
root           2       0  0 7月19 ?       00:00:00 [kthreadd]
root           3       2  0 7月19 ?       00:00:00 [rcu_gp]
root           4       2  0 7月19 ?       00:00:00 [rcu_par_gp]
root           6       2  0 7月19 ?       00:00:00 [kworker/0:0H-kblockd]
root           8       2  0 7月19 ?       00:00:00 [mm_percpu_wq]
root           9       2  0 7月19 ?       00:00:04 [ksoftirqd/0]
root          10       2  0 7月19 ?       00:00:36 [rcu_sched]
root          11       2  0 7月19 ?       00:00:00 [migration/0]

PID 表示進程Id,PPID是父進程id。

先有父親,然後有兒子,我們可以看到有許多進程的 PPID 是 1:

UID          PID    PPID  C STIME TTY          TIME CMD
root         889       1  0 7月19 ?       00:08:41 /usr/sbin/NetworkManager --no-daemon
root         890       1  0 7月19 ?       00:00:00 /usr/bin/python3 /usr/bin/location.py
root         894       1  0 7月19 ?       00:00:00 /usr/bin/python3 /usr/bin/hedron-domain-hook.py
root         897       1  0 7月19 ?       00:00:04 /usr/sbin/kylin-daq-daemon
root         903       1  0 7月19 ?       00:00:00 /usr/bin/systime
root         906       1  0 7月19 ?       00:00:00 /usr/bin/miracat_uibcctl
root         907       1  0 7月19 ?       00:00:00 /bin/bash /usr/bin/execstart.sh
syslog       910       1  0 7月19 ?       00:00:00 /usr/sbin/rsyslogd -n -iNONE

PID 是 1 的進程通常是操作系統的啟動進程(叫init),是所有進程的祖先進程,它是系統啟動時第一個被創建的進程。

STIME 是進程啟動的時間,例如這裡是7月19,如果是24小時內,則會顯示 13:11 類似的時間。

Time 指從啟動到當前,一共花費cpu多長時間。

我們可能會疑惑:第一個進程(PID=1)從昨天開始運行,到現在才花費 cpu 19秒,這個進程不是一直都在嗎?請看下節

Tip: ps -efps aux 都是用於顯示當前系統運行的進程信息,但輸出格式略有差異。

pjl@pjl-pc:~/linux-test$ ps aux | head
USER         PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root           1  0.0  0.1 168768 11008 ?        Ss   7月19   0:19 /sbin/init splash
root           2  0.0  0.0      0     0 ?        S    7月19   0:00 [kthreadd]
root           3  0.0  0.0      0     0 ?        I<   7月19   0:00 [rcu_gp]
root           4  0.0  0.0      0     0 ?        I<   7月19   0:00 [rcu_par_gp]
root           6  0.0  0.0      0     0 ?        I<   7月19   0:00 [kworker/0:0H-kblockd]
root           8  0.0  0.0      0     0 ?        I<   7月19   0:00 [mm_percpu_wq]
root           9  0.0  0.0      0     0 ?        S    7月19   0:04 [ksoftirqd/0]
root          10  0.0  0.0      0     0 ?        I    7月19   0:36 [rcu_sched]
root          11  0.0  0.0      0     0 ?        S    7月19   0:00 [migration/0]
用令牌計算CPU使用率

我們可以同時在電腦上乾很多事,比如寫作、聽音樂、玩游戲...,cpu 不是同一時刻做多件事(cpu 同一時刻只能執行一條指令),而是一會幹這個,一會幹那個,只是速度非常快。

cpu 工作方式是這樣的:有好多任務等待 cpu 處理,根據先來後到的原則以及優先順序的不同,會給任務分配CPU令牌(也就是時間片)。

為了方便理解,假如一個時間片是1秒,在60秒內,cpu 的工作情況如下:

10秒 20秒 10秒 10秒 10秒
進程01 cpu沒事做 進程01 進程02 進程03

cpu 給進程01分配了20秒的時間,進程01的cpu使用率是20/60≈33%。

如果需要瞬時的使用率,將這60秒想象成1秒即可。

通過 ps aux 可以查看當前系統運行的進程,裡面就有 ping,進程號是 486803:

// 存在 ping 進程
pjl@pjl-pc:~$ ps aux |egrep 'ping|PID'
USER         PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
pjl   486803  0.0  0.0  12028   840 pts/1    S    15:58   0:00 ping 192.168.1.110
pjl   489792  0.0  0.0  11652   692 pts/0    S+   16:07   0:00 grep -E --color=auto ping|PID

上文我們留了一個問題:某個進程從昨天開始運行,到現在為止才花費 cpu 19秒。

這個進程可能只需要在特定事件或觸發條件下執行任務,並且在其他時間內保持休眠或空閑狀態。

我們啟動一個進程,讓 cpu 負荷:

// 會一直運行下去
pjl@pjl-pc:~$ md5sum /dev/zero &
[1] 141089

執行 top 命令:

top - 10:48:29 up 8 days, 17:13,  2 users,  load average: 75.53, 82.12, 83.52
任務: 944 total,   8 running, 936 sleeping,   0 stopped,   0 zombie
%Cpu(s): 22.6 us, 35.7 sy,  0.0 ni, 41.7 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
MiB Mem :   7890.4 total,   2118.1 free,   2614.4 used,   3157.8 buff/cache
MiB Swap:   9468.0 total,   9392.5 free,     75.5 used.   5055.7 avail Mem

 進程號 USER      PR  NI    VIRT    RES    SHR    %CPU  %MEM     TIME+ COMMAND
 141089 pjl   20   0   10596    484    420 R  93.3   0.0   1:00.62 md5sum
 143856 root      20   0   12336   2208   2016 S  10.8   0.0   0:00.24 ping
 134506 pjl   20   0   26996   7032   5564 R   9.0   0.1   0:12.68 sshd
 143657 root      20   0   12336   2408   2216 S   7.6   0.0   0:00.37 ping
 143665 root      20   0   12336   2208   2016 S   7.6   0.0   0:00.36 ping

抽取這段信息來看,md5sum cpu 使用率 93.3,而CPU空閑的時間比例(41.7 id) 是 41.7,也就是 cpu 使用率是 58.3,對不上!

// 空閑時間(id)
%Cpu(s): 22.6 us, 35.7 sy,  0.0 ni, 41.7 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st

 進程號 USER      PR  NI    VIRT    RES    SHR    %CPU  %MEM     TIME+ COMMAND
 141089 pjl   20   0   10596    484    420 R  93.3   0.0   1:00.62 md5sum

在按一下鍵盤 1,筆者這裡顯示有4個核,所以 58.3 是4核總共的 cpu 使用率。

top - 10:49:01 up 8 days, 17:14,  2 users,  load average: 91.78, 86.05, 84.82
任務: 966 total,  42 running, 923 sleeping,   0 stopped,   1 zombie
// 4 核
%Cpu0  : 34.6 us, 30.6 sy,  0.0 ni, 34.8 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu1  :  1.1 us, 33.7 sy,  0.0 ni, 65.2 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu2  :  7.6 us, 41.6 sy,  0.0 ni, 50.7 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu3  : 32.7 us, 37.2 sy,  0.0 ni, 30.1 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
MiB Mem :   7890.4 total,   2115.8 free,   2616.2 used,   3158.3 buff/cache
MiB Swap:   9468.0 total,   9392.5 free,     75.5 used.   5053.9 avail Mem

 進程號 USER      PR  NI    VIRT    RES    SHR    %CPU  %MEM     TIME+ COMMAND
 141089 pjl   20   0   10596    484    420 R  90.0   0.0   1:09.05 md5sum
 144346 root      20   0   12336   2136   1944 R   8.7   0.0   0:00.27 ping
 144364 root      20   0   12336   2308   2116 R   6.5   0.0   0:00.20 ping
 144354 root      20   0   12336   2236   2044 R   6.1   0.0   0:00.19 ping
 134506 pjl   20   0   26996   7032   5564 S   5.8   0.1   0:13.91 sshd
 144248 root      20   0   12336   2124   1932 R   5.5   0.0   0:00.37 ping
 144370 root      20   0   12336   2124   1932 R   3.2   0.0   0:00.10 ping
 144371 root      20   0   12336   2124   1932 R   2.9   0.0   0:00.09 ping
 144280 root      20   0   12336   2204   2012 S   2.6   0.0   0:00.15 ping
 144345 root      20   0   12336   2236   2044 S   2.6   0.0   0:00.08 ping
作者:彭加李
出處:https://www.cnblogs.com/pengjiali/p/17578893.html
本文版權歸作者和博客園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接。

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • ### 歡迎訪問我的GitHub > 這裡分類和彙總了欣宸的全部原創(含配套源碼):[https://github.com/zq2599/blog_demos](https://github.com/zq2599/blog_demos) ### 本篇概覽 - 本文是《quarkus依賴註入》系列的第 ...
  • [toc] # Autofac Autofac 是一款超贊的.NET IoC 容器 . 它管理類之間的依賴關係, 從而使 應用在規模及複雜性增長的情況下依然可以輕易地修改 . 它的實現方式是將常規的.net類當做 組件 處理. 控制反轉背後的核心思想是, 我們不再將應用中的類捆綁在一起, 讓類自己去 ...
  • Swagger是一個規範且完整的框架,用於生成、描述、調試和可視化Restfull風格的Web服務。Swagger的目標是對Rest API定義一個標準且和語言無關的介面,可以讓人和電腦擁有無需訪問源碼、文檔或網路流量監控就可以發現和連接服務的能力。當通過Swagger進行正確定義,用於可以理解遠... ...
  • # Unity IPostprocessBuildWithReport Unity IPostprocessBuildWithReport是Unity引擎中的一個非常有用的功能,它可以讓開發者在構建項目後自動執行一些操作,並且可以獲取構建報告。這個功能可以幫助開發提高工作效率,減少手動操作的時間和錯 ...
  • 個人博客 前端:https://lujiesheng.cn 個人博客 後端:https://api.lujiesheng.cn 個人博客 運維:https://portainer.lujiesheng.cn # 1. 伺服器準備 我採用的是 騰訊雲輕量應用伺服器(2C 4G 8M 80G),配置如下 ...
  • 我的一位朋友前陣子遇到一個問題,問題的核心就是try……catch……finally中catch和finally代碼塊到底哪個先執。這個問題看起來很簡單,當然是“catch先執行、finally後執行”了?真的是這樣嗎? 有下麵一段C#代碼,請問這段代碼的執行結果是什麼? public static ...
  • ### 用Xshell 遠程連接虛擬機 如果按[前面博客](https://www.cnblogs.com/AndrewNotes/p/17589321.html)裝好虛擬機,**會發現剛裝好的虛擬機直接連Xshell連不上,宿主機也ping不通虛擬機,這就需要修改VMware的預設網路配置** * ...
  • ### Linux簡介 ```bash # Linux是什麼? 與大家熟知的 Windows 操作系統軟體一樣,Linux 也是一個操作系統軟體。但是與Windows 不同的是,Linux 是一套開放源代碼程式的、並且可以自由傳播的類 Unix操作系統軟體。其在設計之初,就是基於 Intel x86 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...