淺析進程概念以及進程狀態

一、進程是什麼?

程序:完成特定任務的一系列指令的集合。(官方定義)

進程:

  • (用戶角度):程序的一次動態執行過程。
  • 分時系統:時間片輪轉
  • (操作系統角度):進程是操作系統分配資源的基本單位,也是最小單位

進程是怎樣被操作系統管理起來?
先將進程描述起來,再將進程組織起來。那麼問題來了,操作系統怎樣去描述進程?這是就輪到我們PCB出場了
PCB就是描述進程的結構體(所有進程控制塊的統稱),在Linux中,描述進程的結構體叫做task_struct,它會被裝載到內存裏幷包含着進程的信息

task_struct結構體內容

* 標識符:描述進程的唯一標示符,用來區別其他進程
* 狀態:任務狀態(退出信號......)
* 優先級:相對於其他進程的優先級(意味着那個進程將先進行)
* 上下文數據:進程執行時處理器的寄存器中的數據
* 內存指針:包括程序代碼和進程相關數據的指針,還有和其他進程共享的內存塊指針
* 程序計數器:程序中即將被執行的下一條指令的地址
* I/O狀態信息:包括顯示的I/O請求,分配給進程的I/O設備和被進程使用的文件列表
* 其他信息

進程和程序的區別?
答:

* 進程是動態的,程序是靜態的
* 進程的生命週期短暫,程序永久
* 進程有重要的數據結構PCB
* 一個進程只能對應一個程序,一個程序可以對應多個進程
* 程序:數據 + 代碼;   進程:數據 + 代碼 + 堆棧 + PCB(PCB是前三個(數據、代碼、堆棧)的粘合劑)

二、創建進程——fork(系統調用)

fork有兩個返回值

  • (1)給父進程返回子進程的pid,給子進程返回0.
  • (2)失敗返回-1
    why(爲什麼給父進程返回的是子進程的pid,而子進程就不用返回父進程的pid嘞)?
    因爲:父進程必須拿到子進程的pid,這樣父進程就可以知道子進程是哪一個;而子進程不用返回pid是因爲子進程知道自己的父進程是誰。

fork之後,父子進程共享代碼,數據各自開闢空間,私有一份(通過寫實拷貝)(因爲進程在運行時具有獨立性)
並且fork之後一般需要用if分流

如圖:父進程fork出子進程,代碼共享
這裏寫圖片描述
代碼:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>

int main()
{
        printf("beforn fork");

        pid_t pid = fork();

        if(pid == -1)
        {
                printf("%s\n",  strerror(errno));
                exit(1);
        }

        if(pid > 0)
        {
                printf("I  am  parent\n");
        }
        else
        {

                  printf("I  am  child\n");
        }
        printf("finish\n");
        return 0;
}

讀者可以自行驗證

二、進程狀態
進程狀態反映了進程執行過程的變化。這些狀態隨進程的執行和外界條件的變化而轉換。 在三態模型中,進程狀態分爲三個基本狀態:

* 運行態: 進程佔有處理器正在處理
* 阻塞態:進程不具備運行條件,正在等待某個事件的完成
* 就緒態:進程具備運行條件,等待系統分配處理器以便運行


Linux下進程的六種狀態

* R運行狀態(running):並不意味着進程一定正在運行,它表明進程要麼是在運行要麼是在運行隊列裏
* S睡眠狀態(sleeping):意味着進程在等待事件的完成
* D磁盤休眠狀態(Disk sleep):有時候也叫作不可中斷睡眠,在這個狀態的進程通常會等待IO的結束
* T停止狀態(stopped):可以通過發送SIGSTOP信號來停止進程。這個被暫停的進程可以通過發送SIGCONT信號讓進程繼續運行
* X死亡狀態(dead):這個狀態只有一個返回狀態,你不會在任務列表裏面看到這個狀態
* Z殭屍狀態(zombies):它是一種較爲特殊的狀態。當進程退出並且父進程沒有讀取到子進程退出的返回代碼時就會產生僵死(屍)進程

進程狀態在用戶態和內核態之間的轉換圖:
這裏寫圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章