進程狀態轉換圖

一、進程狀態轉換基礎

進程是操作系統調度的基本單位,而進程狀態則是描述進程執行過程中狀態的基本概念。進程在其生命周期中會處於不同的狀態,包括新建態、就緒態、運行態、阻塞態和終止態。

新建態是指進程被創建後還未被分配資源的狀態,就緒態是指進程已經獲取到了所有必要資源等待執行的狀態,運行態是指進程正在佔用CPU運行的狀態,阻塞態是指進程等待某些條件滿足或資源釋放的狀態,終止態是指進程執行結束且已經被釋放的狀態。

當進程在不同狀態之間切換的時候,需要進行狀態轉換操作。下面我們以Linux作為例子來介紹進程在狀態之間的轉換操作。

/* 進程狀態 */
enum task_state {
    TASK_RUNNING = 0,   /* 運行態 */
    TASK_INTERRUPTIBLE, /* 可中斷的睡眠態 */
    TASK_UNINTERRUPTIBLE,   /* 不可中斷的睡眠態 */
    TASK_STOPPED,   /* 停止態 */
    TASK_TRACED,    /* 被追蹤態 */
    TASK_DEAD,  /* 已終止態 */
};

二、進程狀態轉換圖

進程的狀態轉換有多種可能,這裡我們以一種典型的轉換方式為例來說明。下面是進程狀態轉換圖:

+--------+        +----------+       +---------+       +---------+
| 創建態 +------->+ 就緒態   +------>+ 運行態  +------>| 終止態  |
+--------+        +----------+       +---------+       +---------+
                   ^   |  ^                |
                   |   |  |                |
                   |   V  |                |
             +--------------+         +-----------+
             | 可中斷的睡眠態 |<--------+ 不可中斷的睡眠態 |
             +--------------+         +-----------+

三、進程狀態之間的轉換

下面我們來分別介紹進程狀態之間的轉換方式。

1. 創建態到就緒態

當一個進程被創建時,初始狀態為創建態。當進程被分配到所有必要資源,可以開始執行之前,由創建態轉為就緒態。這個轉換是由系統調度算法決定的,通常是通過進程隊列和調度程序來實現的。

/* 創建一個新進程並將其加入到就緒隊列 */
struct task_struct *init_task(void)
{
    /* ...省略其他代碼... */
    /* 創建進程 */
    p = __alloc_task_struct();
    /* 設置進程狀態為就緒態 */
    p->state = TASK_RUNNING;
    /* 將進程加入到就緒隊列 */
    enqueue_task(p, &rq->array[rq->curr]);
    return p;
}

2. 就緒態到運行態

當CPU被分配到了進程時,該進程進入運行態。如果此時還有其他進程處於就緒態,則它們將繼續等待CPU資源的分配。

/* 進程從就緒態變為運行態 */
static void __sched __schedule(void)
{
    /* ...省略其他代碼... */
    /* 獲取就緒隊列里的下一個進程,並將其狀態設置為運行態 */
    next = pick_next_task(rq);
    next->state = TASK_RUNNING;

    /* 切換到下一個進程 */
    rq->curr = next;
    context_switch(rq, prev, next);
}

3. 運行態到就緒態

當一個進程正在佔用CPU運行時,如果出現IO等等其它需要等待的操作,則該進程從運行態進入阻塞態,然後進入可中斷的睡眠態或者不可中斷的睡眠態,等待IO等操作結束後再轉為就緒態。此時,其他進程有可能獲得CPU使用權。

/* 進程從運行態變為阻塞態 */
void sleep_on(wait_queue_head_t *q)
{
    /* ...省略其他代碼... */
    //將當前進程的狀態設置為可中斷的睡眠態
    current->state = TASK_INTERRUPTIBLE;
    //將當前進程加入到等待隊列中
    add_wait_queue(q, &wait);
    //切換到下一個進程
    schedule();
}

4. 阻塞態到就緒態

當阻塞態的進程等待的系統調用返回並且獲得了系統資源時,它從睡眠態或者阻塞態變成就緒態,表示該進程的資源需求已得到滿足,可以開始運行了。

/* 進程從阻塞態變為就緒態 */
void wake_up(wait_queue_head_t *q)
{
    /* ...省略其他代碼... */
    //將等待隊列中阻塞進程的狀態設置為就緒態
    do_each_thread(g, p) {
        if (p->state == state &&
            (wait == NULL || wait->func(wait, task, mode, key) != 0))
            p->state = TASK_RUNNING;
    } while_each_thread(g, p);
    /* 移除等待隊列中的進程 */
    __remove_wait_queue(q, &wait);
    /* 切換到下一個進程 */
    schedule();
}

5. 運行態到終止態

進程在完成任務後或者出錯時,會從運行態進入終止態。在終止態中,進程進行善後處理和資源釋放。此後,內核將不再管理此進程,以便其它進程使用其資源。

/* 進程從運行態變為終止態 */
asmlinkage void do_exit(long code)
{
    /* ...省略其他代碼... */
    //設置進程狀態為終止態
    current->state = TASK_DEAD;
    //從進程表中刪除該進程
    del_from_tasklist(current);
    /* 切換到下一個進程 */
    schedule();
}

結語

進程的狀態轉換是操作系統中非常關鍵的一個概念。我們通過介紹進程的五種狀態和相應的轉換方式,使讀者加深對進程狀態轉換的理解。其實,在Linux系統中還有很多其它的狀態轉換方式,大家可以自行深入學習。

原創文章,作者:BKLI,如若轉載,請註明出處:https://www.506064.com/zh-hant/n/133751.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
BKLI的頭像BKLI
上一篇 2024-10-04 00:01
下一篇 2024-10-04 00:01

相關推薦

  • 如何通過jstack工具列出假死的java進程

    假死的java進程是指在運行過程中出現了某些問題導致進程停止響應,此時無法通過正常的方式關閉或者重啟該進程。在這種情況下,我們可以藉助jstack工具來獲取該進程的進程號和線程號,…

    編程 2025-04-29
  • Java中的殭屍進程簡介與解決方法

    本文將對Java中的殭屍進程進行詳細闡述,並給出幾種解決方法。 一、殭屍進程的概念 在操作系統中,進程是指正在執行的程序。當一個進程創建了一個子進程,而該子進程完成了任務卻沒有被父…

    編程 2025-04-27
  • 多線程和多進程的應用

    多線程和多進程是現代編程中常用的技術,可以提高程序的效率和性能。本文將從不同的角度對多線程和多進程進行詳細的介紹和應用。 一、多線程 vs 多進程 多線程和多進程都是為了實現程序並…

    編程 2025-04-27
  • Python多進程讀取數據

    本文將從多個方面詳細闡述在Python中如何通過多進程讀取數據,並給出完整的代碼示例。 一、多進程概述 在計算機科學中,進程是正在執行的程序實例。多進程是指計算機系統同時執行多個進…

    編程 2025-04-27
  • 進程a與進程b共享變量s1

    本文將從多個方面對進程a與進程b共享變量s1做詳細的闡述,並給出代碼示例。 一、定義全局變量s1 進程a與進程b共享變量s1,意味着s1是一個全局變量。在C語言中,可以使用關鍵字e…

    編程 2025-04-27
  • python多進程並行循環

    在大數據時代,我們通常需要處理大量的數據。處理大數據往往需要較長的時間,影響效率。Python提供了多線程、多進程等並行處理方式來提高數據處理效率。本文將主要講解python多進程…

    編程 2025-04-27
  • Python進程池共享內存用法介紹

    本文將從多個方面詳細闡述Python進程池共享內存的相關知識,包括如何使用進程池、進程池的實現原理、進程池中的共享內存管理等。本文內容將涵蓋: 一、進程池的使用 進程池是一種有效的…

    編程 2025-04-27
  • Linux守護進程

    一、什麼是Linux守護進程 Linux守護進程是在Linux系統下運行的一種特殊進程,它沒有終端連接,並且在後台運行,通常用於某些服務程序、監控程序或者系統管理程序等。守護進程的…

    編程 2025-04-25
  • Python 進程通信

    當需要在不同進程之間進行通信時,Python 提供了幾種方法來實現進程間通信。這些方法包括隊列,管道,共享內存以及套接字。 1. 隊列 Python 隊列是進程安全的,並且可以很方…

    編程 2025-04-24
  • Linux下殺掉進程的命令詳解

    一、殺掉進程的概念 在進行Linux系統管理以及軟件開發過程中,我們常常需要殺掉卡死或異常程序的進程。殺掉進程是指在運行中的進程突然中斷或終止運行,也稱為進程終止。 殺掉進程的主要…

    編程 2025-04-24

發表回復

登錄後才能評論