21.1 進程查看和進程狀態
21.1.1 ps 指令
ps 指令通常可以查看到進程的 ID、進程的用戶 ID、進程狀態和進程的 Command
ps:查看當前用戶啟動的進程
ps -ef:詳細查看后台進程信息,可以用 ps -ef | more 進行分屏查看
ps -aux:當前運行的進程占用的CPU的時間,內存的時間
- USER:進程的屬組
- PID:進程的ID
- PPID:父進程
- %CPU:進程占用的CPU百分比
- %MEM:占用內存的百分比
- NI:進程的 NICE值,數值大,表示較少占用CPU的時間
- VSZ:進程虛擬大小
- RSS:駐留中頁的數量
- TTY:終端ID
- WCHAN:正在等待的時間
- START:啟動進程的時間
- STAT:進程的狀態
- TIME:進程消耗CPU的時間
- COMMAND:命令的名稱和參數
21.1.2 進程狀態
- linux上進程有5種狀態:
- 運行(正在運行或在運行隊列中等待)
- 中斷(休眠中, 受阻, 在等待某個條件的形成或接受到信號) ---可中斷等待狀態
- 不可中斷(收到信號不喚醒和不可運行, 進程必須等待直到有中斷發生)---不可中斷等待狀態
- 僵死(進程已終止, 但進程描述符存在, 直到父進程調用wait4()系統調用后釋放)
- 停止(進程收到SIGSTOP, SIGSTP, SIGTIN, SIGTOU信號后停止運行運行)
- ps工具標識進程的5種狀態碼:
- D 不可中斷 uninterruptible sleep (usually IO)
- R 運行 runnable (on run queue)
- S 中斷 sleeping
- T 停止 traced or stopped
- Z 僵死 a defunct ("zombie") process
注: 其它狀態還包括W(無駐留頁), <(高優先級進程), N(低優先級進程), L(內存鎖頁).
21.2 進程調度和進程狀態變化
21.2.1 進程調度
進程如何進行調度:
- 第一步:處理內核中的工作
- 第二步:處理當前進程
- 第三步:選擇進程
- 實時進程
- 普通進程
- 第四步:進程交換
啟動進程之后,會啟動一個 task_struct 結構體,在此結構體中會存儲進程調度的一些信息。task_struct 中的調度信息:
- 策略
- 輪流策略
- 先進先出策略
- 優先權
- Jiffies 變量
- 實時優先權
- 實時進程之間
- 計數器
21.2.2 進程狀態變化關系
21.3 進程標識
內核通過 PID 來區分不同的進程
1 #include <unistd.h> 2 #include <sys/types.h> 3 4 pid_t getpid(void); //獲得當前進程ID 5 uid_t getuid(void);//獲得當前進程的實際用戶ID 6 uid_t geteuid(void);//獲得當前進程的有效用戶ID 7 gid_t getgid(void);//獲得當前進程的用戶組ID 8 pid_t getppid(void);//獲得當前進程的父進程ID 9 pid_t getpgrp(void);//獲得當前進程所在的進程組ID 10 pid_t getpgid(pid_t pid);//獲得進程ID 為 pid 的進程所在的進程組 ID
- 實際用戶:即登陸的用戶ID,自己的賬號登陸系統后,輸入 id ,即可查看到自己的用戶ID,當前登陸進去的用戶即為實際用戶。可以用當前用戶啟動很多進程。
- 有效用戶:在登陸實際用戶后,我們仍然可以用不同的用戶來啟動進程,比如 root 用戶。這種就使在執行進程的時候以一種特定的身份去啟動,這個身份就是有效用戶。一般情況下,有效用戶就是實際用戶。
例子:process_id.c
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <unistd.h> 4 #include <sys/types.h> 5 6 int main(void) 7 { 8 printf("pid: %d\n", getpid());//獲得當前啟動進程的進程編號 9 printf("uid: %d\n", getuid());//獲得當前實際用戶的ID 10 printf("ppid: %d\n", getppid());//獲得當前執行進程的父進程號 11 printf("euid: %d\n", geteuid());//獲得當前有效用戶的 ID 12 printf("user gid: %d\n", getgid());//獲得用戶的組ID 13 printf("gid: %d\n", getpgrp());//獲得當前進程組的ID 14 printf("pgid: %d\n", getpgid(getpid()));//獲得指定進程的進程組ID 15 printf("ppgid: %d\n", getpgid(getppid()));//獲得當前父進程所在的進程組的ID 16 17 return 0; 18 }
當前 ppid 即父進程ID為8468,為當前 shell 的進程
uid 為用戶組 ID,我們當前用戶的id 為1000,用戶組的 ID 為 1000
實際用戶和有效用戶區別:
查看當前要運行的進程的所在組,可以看見文件的實際用戶和實際用戶組都為 rk3399
進入 root 模式修改文件的所屬組:sudo chown root.root bin/process_id
修改粘着位,通過修改粘着位可以修改啟動進程的有效用戶:
sudo chmod u+s bin/process_id //增加粘着位
s 就是粘着位的設置,為文件添加有效用戶
可以看見增加了一個 s,執行權限變為了 s
運行程序:
可以看見實際用戶還是我們當前的用戶,有效用戶 euid 變為了 root
當針對文件擁有者本身修改粘着位以后,在運行進程的時候,可以將原先用戶的權限(rk3399)提升位文件擁有者(root)的權限。