【Linux探索學習】第十三彈——進程狀態:深入理解操作系統進程狀態與Linux操作系統中的進程狀態

linux筆記:

https://blog.csdn.net/2301_80220607/category_12805278.html?spm=1001.2014.3001.5482

前言:

操作系統中,進程是資源分配和任務調度的基本單位。為了更好地管理系統資源,操作系統將進程的生命周期劃分為不同的狀態,幫助系統實現高效的資源調度與管理。linux操作系統在經典的進程狀態模型基礎上進行了擴展和細化,提供了更細粒度的控制。本文將詳細介紹操作系統進程狀態的基本概念,深入解析linux操作系統中的進程狀態,并通過代碼示例展示各個狀態的實現方式。

一、操作系統中的進程狀態概述

操作系統中的進程狀態是進程在生命周期中可能處于的不同狀態。這些狀態幫助操作系統識別進程的運行情況,并在不同狀態間進行合理的資源分配。操作系統中的經典進程狀態包括就緒、運行、阻塞和終止。

1.1 經典的進程狀態模型

典型的操作系統中,進程狀態可以分為以下幾種:

狀態

描述

就緒(Ready)

進程已準備好,等待CPU調度器分配CPU。

運行(Running)

進程正在占用CPU,正在執行中。

阻塞(Blocked/Waiting)

進程因需要等待資源或事件而無法繼續執行,暫停等待。

終止(Terminated)

進程執行完成或被強制終止,進入終止狀態,等待操作系統回收資源。

在這種經典模型中,進程會在不同狀態之間流轉。具體來說:

就緒 -> 運行:CPU調度器分配CPU給就緒狀態的進程。運行 -> 阻塞:進程等待I/O或其他資源時進入阻塞狀態。阻塞 -> 就緒:等待的條件滿足后,進程重新進入就緒隊列,等待CPU調度。運行 -> 終止:進程執行完畢或異常終止,進入終止狀態。1.2 進程狀態轉換圖

【Linux探索學習】第十三彈——進程狀態:深入理解操作系統進程狀態與Linux操作系統中的進程狀態

該圖展示了一個經典進程狀態的轉換流程。箭頭表示進程狀態轉換的可能路徑。

二、Linux操作系統中的進程狀態

Linux操作系統在經典的進程狀態基礎上進行了一系列擴展,允許內核更細粒度地控制進程,尤其是當系統資源緊張或多任務并發性很高時。Linux內核中的進程狀態可以使用ps命令或讀取/proc文件系統來查看進程的狀態信息。

2.1 Linux進程狀態的分類

Linux狀態

描述

TASK_RUNNING

正在運行或可以運行的進程,即就緒狀態。

TASK_INTERRUPTIBLE

可中斷等待狀態,等待期間可以被信號中斷并喚醒。

TASK_UNINTERRUPTIBLE

不可中斷等待狀態,等待期間不會被信號喚醒,通常用于等待設備I/O操作的完成。

TASK_STOPPED

進程被暫停,通常因收到SigsTOP等信號。

TASK_TRACED

進程被調試器(如gdb)控制。

EXIT_DEAD

進程已結束,即將被回收。

EXIT_ZOMBIE

僵尸狀態,進程結束但資源尚未被父進程回收。

TASK_DEAD

進程已徹底終止,資源已回收。

在進程的task_struct結構體中,state字段用來表示進程的當前狀態。根據內核中的定義,不同狀態的進程會被掛載在不同的等待隊列上,以實現細粒度的調度與控制。

2.2 各狀態的詳細解釋 TASK_RUNNING:進程正在運行或準備運行。它可以被調度器分配到CPU執行。TASK_RUNNING的進程始終是就緒隊列的一部分。 TASK_INTERRUPTIBLE:進程處于可中斷等待狀態,等待某一條件滿足。進程在此狀態下可以被信號喚醒。(關于信號的知識我們在后面會講) TASK_UNINTERRUPTIBLE:進程處于不可中斷的等待狀態。這通常用于等待特定資源(例如設備I/O操作完成)。進程在此狀態下不會被信號打斷,即便外部發送信號也不會響應。 TASK_STOPPED:進程被暫停,通常是由于接收到SIGSTOP信號或調試器干預,等待繼續或恢復信號。 TASK_TRACED:進程被調試工具(如gdb)跟蹤和控制。此狀態下的進程會暫停,直到調試器進一步控制。 EXIT_DEAD:進程終止后進入清理階段,等待系統回收資源。 EXIT_ZOMBIE:進程已結束,系統未回收其資源。僵尸進程會保留在系統中,直到其父進程調用wait()系統調用收集它的退出狀態。 TASK_DEAD:表示進程已徹底結束,系統已回收其所有資源。 2.3 Linux進程狀態表

Linux 狀態

符號

進程描述

TASK_RUNNING

R

進程正在運行或可以被調度器調度運行。

TASK_INTERRUPTIBLE

S

進程處于可中斷的睡眠狀態,等待條件滿足。

TASK_UNINTERRUPTIBLE

D

進程處于不可中斷的睡眠狀態,通常等待I/O。

TASK_STOPPED

T

進程暫停或已終止。

EXIT_ZOMBIE

Z

僵尸進程,等待父進程收回。

2.4 使用ps查看進程狀態

在Linux系統中,可以通過ps命令查看進程的狀態:

代碼語言:JavaScript代碼運行次數:0運行復制

ps -aux

ps命令會顯示每個進程的詳細信息,其中狀態列標記著每個進程的狀態。狀態的含義如下:

R:運行或就緒狀態。S:可中斷等待。D:不可中斷等待。T:停止。Z:僵尸狀態。

我們也可以通過ps命令查看某個指定的進程的信息:

代碼語言:javascript代碼運行次數:0運行復制

ps axj | grep 進程名字

三、代碼示例:實現Linux進程狀態的模擬

為了更好地理解Linux中的進程狀態,以下示例演示了不同狀態的應用。代碼展示了一個簡單的內核模塊,用于模擬進程進入阻塞狀態、喚醒狀態等。

3.1 阻塞等待狀態示例代碼語言:javascript代碼運行次數:0運行復制

#include <linux/module.h>#include <linux/kernel.h>#include <linux/init.h>#include <linux/sched.h>#include <linux/wait.h>#include <linux/kthread.h>#include <linux/delay.h>static wait_queue_head_t wait_queue;  // 定義等待隊列static int condition = 0;static struct task_struct *thread_waiter;static int waiter_thread(void *data) {    printk(KERN_INFO "等待線程啟動...n");    wait_event_interruptible(wait_queue, condition != 0);  // 可中斷等待    printk(KERN_INFO "等待線程被喚醒,繼續執行...n");    return 0;}static int __init wait_queue_init(void) {    init_waitqueue_head(&wait_queue);  // 初始化等待隊列    thread_waiter = kthread_run(waiter_thread, NULL, "waiter_thread");    if (IS_ERR(thread_waiter)) {        printk(KERN_ERR "線程創建失敗n");        return PTR_ERR(thread_waiter);    }    msleep(5000);  // 模擬一些操作    condition = 1;  // 修改條件    wake_up_interruptible(&wait_queue);  // 喚醒等待線程    return 0;}static void __exit wait_queue_exit(void) {    printk(KERN_INFO "卸載模塊n");}module_init(wait_queue_init);module_exit(wait_queue_exit);MODULE_LICENSE("GPL");

在上面的代碼中:

waiter_thread進入可中斷等待狀態,等待條件滿足。當條件變量condition改變時,wake_up_interruptible喚醒等待隊列中的線程,使waiter_thread進入可運行狀態。3.2 僵尸進程示例

僵尸進程是進程狀態的特殊情況,無法直接控制其生成。為了生成僵尸進程,可以在一個子進程中完成工作后立刻終止,但不等待父進程收回資源。示例如下:

代碼語言:javascript代碼運行次數:0運行復制

#include <stdio.h>#include <stdlib.h>#include <unistd.h>int main() {    pid_t pid = fork();    if (pid == 0) {        // 子進程,立即退出成為僵尸進程        printf("子進程:PID=%dn", getpid());        exit(0);    } else {        // 父進程,等待5秒以查看僵尸進程        printf("父進程:PID=%dn", getpid());        sleep(5);        printf("父進程結束,僵尸子進程將被回收。n");    }    return 0;}

在這個代碼中,子進程在終止后不被父進程立即回收,因此變成僵尸狀態。可以使用ps命令查看該僵尸進程,發現它的狀態為Z。

3.3 孤兒進程示例

除了

? 版權聲明
THE END
喜歡就支持一下吧
點贊9 分享