目錄

進程狀態

Z(zombie)-殭屍進程

殭屍進程的核心危害

解決方法(按實用優先級排序)

孤兒進程

進程優先級

基本概念

查看系統進程

PRI and NI

查看進程優先級的命令

其他概念


進程狀態

在Linux內核裏,進程有時候也叫做任務

  • R運行狀態(running): 並不意味着進程一定在運行中,它表明進程要麼是在運行中要麼在運行隊列裏
  • S睡眠狀態(sleeping): 意味着進程在等待事件完成(這裏的睡眠有時候也叫做可中斷睡眠(interruptible sleep))
  • D磁盤休眠狀態(Disk sleep)有時候也叫不可中斷睡眠狀態(uninterruptible sleep),在這個狀態的進程通常會等待IO的結束。
  • T停止狀態(stopped): 可以通過發送 SIGSTOP 信號給進程來停止(T)進程。這個被暫停的進程可以通過發送 SIGCONT 信號讓進程繼續運行。
  • X死亡狀態(dead):這個狀態只是一個返回狀態,你不會在任務列表裏看到這個狀態

linux進程(02)_父進程


Z(zombie)-殭屍進程

僵死狀態(Zombies)是一個比較特殊的狀態。

  • 當進程退出並且父進程(使用wait()系統調用)沒有讀取到子進程退出的返回代碼時就會產生僵死(屍)進程
  • 僵死進程會以終止狀態保持在進程表中,並且會一直在等待父進程讀取退出狀態代碼。
  • 所以,只要子進程退出,父進程還在運行,但父進程沒有讀取子進程狀態,子進程進入Z狀態
#include <stdio.h>
#include <stdlib.h>
#include<sys/types.h>
#include<unistd.h>
int main()
{
    pid_t id = fork();
    if(id < 0){
        perror("fork");
        return 1;
}
    else if(id > 0){ //parent
    printf("parent[%d] is sleeping...\n", getpid());
    sleep(30);
}else{
    printf("child[%d] is begin Z...\n", getpid());
    sleep(5);
    exit(EXIT_SUCCESS);
}
    return 0;
    }

linux進程(02)_子進程_02


殭屍進程的核心危害

  1. 佔用PID資源:系統PID數量有限(默認通常32768個),殭屍進程累積會耗盡PID,導致無法創建新進程。
  2. 浪費系統資源:雖不佔用CPU/內存,但會留存進程表項(包含PID、退出狀態等信息),消耗內核資源。
  3. 阻塞父進程等待:若父進程未處理子進程退出狀態,可能因持續等待導致自身阻塞

解決方法(按實用優先級排序)

  • 父進程主動等待:用 wait() 或 waitpid() 獲取子進程退出狀態
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>

int main() {
    pid_t pid = fork();
    if (pid == -1) {
        perror("fork failed");
        exit(EXIT_FAILURE);
    } else if (pid == 0) {
        printf("子進程 ID: %d,父進程 ID: %d\n", getpid(), getppid());
        exit(EXIT_SUCCESS);
    } else {
        printf("父進程 ID: %d,創建的子進程 PID: %d\n", getpid(), pid);
        wait(NULL);
        printf("子進程已退出\n");
    }
    return 0;
}
  • 註冊SIGCHLD信號處理函數:子進程退出時內核發SIGCHLD,父進程捕獲後調用 wait() ,適合多子進程場景
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
#include <signal.h>

void sigchld_handler(int signum) {
    pid_t pid;
    while ((pid = waitpid(-1, NULL, WNOHANG)) > 0) {
        printf("子進程 %d 已退出\n", pid);
    }
}

int main() {
    struct sigaction sa;
    sa.sa_handler = sigchld_handler;
    sigemptyset(&sa.sa_mask);
    sa.sa_flags = SA_RESTART;
    sigaction(SIGCHLD, &sa, NULL);

    pid_t pid = fork();
    if (pid == -1) {
        perror("fork failed");
        exit(EXIT_FAILURE);
    } else if (pid == 0) {
        printf("子進程 ID: %d,父進程 ID: %d\n", getpid(), getppid());
        sleep(1);
        exit(EXIT_SUCCESS);
    } else {
        printf("父進程 ID: %d,創建的子進程 PID: %d\n", getpid(), pid);
        while (1) {
            // 模擬父進程繼續執行其他任務
            sleep(1);
        }
    }
    return 0;
}
  • 父進程先於子進程退出:父進程退出後,子進程會被init(PID=1)接管,init會自動回收子進程資源。
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main() {
    pid_t pid = fork();
    if (pid == -1) {
        perror("fork failed");
        exit(EXIT_FAILURE);
    } else if (pid == 0) {
        printf("子進程 ID: %d,父進程 ID: %d\n", getpid(), getppid());
        sleep(3);
        printf("此時父進程已退出,我的新父進程 ID: %d\n", getppid());
        exit(EXIT_SUCCESS);
    } else {
        printf("父進程 ID: %d,創建的子進程 PID: %d\n", getpid(), pid);
        exit(EXIT_SUCCESS);
    }
    return 0;
}
  •  使用 fork() 兩次:子進程創建孫進程後立即退出,孫進程成為孤兒進程被init接管,避免子進程變成殭屍。

孤兒進程

  • 父進程先退出,子進程就稱之為“孤兒進程”
  • 孤兒進程被1號init進程領養,當然要有init進程回收

進程優先級

基本概念

  • cpu資源分配的先後順序,就是指進程的優先權(priority)
  • 優先權高的進程有優先執行權利。
  • 配置進程優先權對多任務環境的linux很有用,可以改善系統性能。還可以把進程運行到指定的CPU上,這樣一來,把不重要的進程安排到某個CPU,可以大大改善系統整體性能。

查看系統進程

在linux或者unix系統中,用ps –l命令則會類似輸出以下幾個內容

linux進程(02)_#include_03

  • UID : 代表執行者的身份
  • PID : 代表這個進程的代號
  • PPID :代表這個進程是由哪個進程發展衍生而來的,亦即父進程的代號
  • PRI :代表這個進程可被執行的優先級,其值越小越早被執行
  • NI :代表這個進程的nice值

PRI and NI

  • PRI即進程的優先級,或者説就是程序被CPU執行的先後順序,此值越小進程的優先級別越高
  • NI是nice值,其表示進程可被執行的優先級的修正數值
  • PRI值越小越快被執行,那麼加入nice值後,將會使得PRI變為:PRI(new)=PRI(old)+nice
  • 這樣,當nice值為負值的時候,那麼該程序將會優先級值將變小,即其優先級會變高,則其越快被執行所以,調整進程優先級,在Linux下,就是調整進程nice值
  • nice其取值範圍是-20至19,一共40個級別。

查看進程優先級的命令

用top命令更改已存在進程的nice:

top

進入top後按“r”–>輸入進程PID–>輸入nice值


 nice  命令(查看/設置新進程的默認優先級)
 
查看默認nice值(未指定時為0)

nice

renice  命令(調整已運行進程的優先級)
 
將PID為1234的進程nice值改為5(降低優先級)

renice 5 -p 1234

其他概念

  • 競爭性: 系統進程數目眾多,而CPU資源只有少量,甚至1個,所以進程之間是具有競爭屬性的。為了高效完成任務,更合理競爭相關資源,便具有了優先級
  • 獨立性: 多進程運行,需要獨享各種資源,多進程運行期間互不干擾
  • 並行: 多個進程在多個CPU下分別,同時進行運行,這稱之為並行
  • 併發: 多個進程在一個CPU下采用進程切換的方式,在一段時間之內,讓多個進程都得以推進,稱之為併發