Linux操作系統中進程,PCB,fork()函數,殭屍進程,孤兒進程,進程優先級,環境變量

操作系統(Operator System)

操作系統有很多種類,但是大的放向有三類。
Windows、MAC、Linux操作系統。
操作系統在計算機中,相當與一個管家,對下合理安排管理計算機資源,對上提供給用戶一個穩定的操作環境。
計算機發展到現在經過不斷的改進,目前使用的是馮諾伊曼體系結構,以內存,CPU,輸入,輸出。
操作系統中內核就是屬於內存管理進程管理等,在操作系統中爲了管理完成一些任務,或者說作業,那麼就會通過描述一個任務,然後進行管理。

計算機實現圖

進程

概念
是一個程序執行的一個實例,程序正在執行。
從內核來看,是分配系統資源的實體。
描述(PCB)
那麼怎麼來描述一個進程呢?
進程的描述是通過PCB來進行描述。在Linux中描述PCB是通過一個叫task_struct的結構體。PCB中有什麼呢?
有這麼幾個:
1. 標識符:用來描述本進程的唯一標識符,區別其他進程
2. 狀態:用來表示當前進程的狀態,退出碼,退出信號
3. 優先級:相對於其他進程之間的優先級
4. 程序計數器:用於記錄程序的下一條指令的地址
5. 內存指針:其中有代碼和數據相關的指針,還有共享內存塊指針
6. 上下文:進程執行時寄存器中的數據
7. I/O狀態
8. 記賬信息:其中包含各種時間
9. 其他

這裏重點說明一下進程的狀態:
進程的狀態有:

1.R:運行狀態。表示的是進程在就緒隊列或者正在運行。這個是不定。
2.S:睡眠狀態。表示進程在等在某件事情完成。
3.D:磁盤休眠。不可中斷睡眠。
4.T:停止狀態。用來停止該進程。用kill 查看對應的編號
5.X:死亡狀態。進程結束。
6.Z:殭屍狀態。既進程結束但是PCB爲釋放

fork()函數

fork函數用來創建一個進程。這個函數是一個很特別的系統函數,怎麼特別呢?
因爲它調用一次有兩個返回值。

fork 返回值類型是pid_t類型。其實就是一個int型,經過封裝後爲pid_t類型。
而且fork函數在創建出子進程時,父子進程代碼共享,數據各自開闢空間,私有一份,並且採用寫時拷貝。

fork函數返回兩個值,那麼我們怎麼進行操作呢?
fork函數是創建出一個子進程,那麼我們可以用if語句來進行分流。在分流前,我們要瞭解到,fork出來的子進程返回值爲0,而父進程的返回值爲子進程的pid。所以我我們就可以用以下代碼進行分流

int main()
{
    pid_t ret = fork();
    if (ret > 0)
    {
        // 父
    }
    else  if (ret == 0)
    {
        // 子
    }
    else
    {
        perror();
}

我們來總結一下fork函數:
1. 一次調用有兩個返回值,父進程返回子進程的pid,子進程返回0
2. 父進程和子進程都從fork執行結束之後的位置繼續執行
3. 子進程以父進程爲模板。採用寫時拷貝
4. 父子進程執行的先後順序,不確定,取決於操作系統調度器

fork()函數創建子進程失敗情況
1)創建進程數達到上限
2)內存滿了,不能有空間進行進程的創建。

殭屍進程

什麼是殭屍進程?
在這裏因爲要說明,殭屍進程也是進程的一個狀態,是Z狀態(zombie)。
怎麼才能進入Z狀態,也就是怎麼產生的殭屍進程。

殭屍進程的產生是因爲在子進程在做完父進程分配好的任務,需要父進程來接受子進程的返回碼,但是父進程沒有接受,這樣子進程就會形成殭屍進程,會以進程終止在進程表中,PCB還在佔用系統資源。
如果父進程還在運行,子進程進入Z狀態,並且佔用系統資源。

產生殭屍進程代碼:

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
int main()
{
    pid_t id = fork();
    if (id > 0)
    {
        // 父進程
        printf("%d\n", gitpid());
        sleep(10);
    }
    else if (id == 0)
    {
        // 子進程
        printf("%d\n", gitpid());
        sleep(5);
    }
    else
    {
        perror("fork");
    }
    return 0;
}

殭屍進程

孤兒進程

什麼是孤兒進程?
孤兒進程簡單的說:
就是當父進程創建出子進程,但是是父進程先退出,子進程還沒退出,就形成了孤兒進程。
如果形成孤兒進程怎麼處理,如果出現孤兒進程,那麼就會由1號進程收養,該進程的父進程變成1好進程Init進程。init進程會每隔一會wait(),直到收回孤兒進程結果,讓孤兒進程正常退出。
用代碼演示孤兒進程:

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
int main()
{
    pid_t id = fork();
    if (id > 0)
    {
        printf("%d", gitpid());
        sleep(1);
    }
    else if (id == 0)
    {
        printf("%d\n", gitpid(), gitppid());
        sleep(10);
    }
    else
    {
        perror("fork");
    }
    return 0;
}

孤兒進程

進程優先級

進程優先級是幹什麼用的。爲什麼會有進程優先級。
進程優先級就決定了,進程執行的先後順序,也就是爲了合理的按照一定順序分配系統資源。
對於一個多任務系統,這樣做大大的改善了系統的整體性能。
怎麼查看Linux下的進程:ps -l
進程
需要知道:
UID:代表執行者的身份
PID:代表進程的唯一標識符
PPID:代表當前進程的父進程。
PRTI:代表進程被執行的優先級,值越小越被先執行
NI:代表進程的NICE值。(nice值也可以叫修正數)
關於優先級,難道就只能按照系統給出的執行嗎?自己不可以修改嗎?
不!
我們可以通過修改NICE值進行修改優先級。但是nice值是有修正範圍的是-20到19,四十個級別。
具體怎麼調整:
調整的規則是 新優先級 = 舊有限級 + nice值
1)程序啓動前調整:nice -n -5 ./a.out
2)調整已經存在的進程優先級:renice -5 -p PID號 (意思是把進程號的nice值修改爲-5)
3)用top命令修改nice值:進入top後按r輸入PID號再輸入nice值
最後再總結一下進程的四個性質

競爭性:進程數量較多,而cpu等資源少,就會形成進程間的競爭。合理的競爭會高效的完成任務。也因此有了優先級
獨立性:多進程運行,有着自己獨有的資源,進程與進程之間不會收到影響。
併發性:併發從宏觀上看是同是運行,其實在微觀上看系統的進程是串行運行,因爲CPU的速度比較快,所以就看上去是同時運行。
並行性:並行就是同時運行多個 進程,這是因爲有多個cpu處理器,達到了同時處理兩個進程或者多個進程。就形成了並行。

Linux下的環境變量

環境變量:一般是指在操作系統中用來指定操作系統運行環境的一些參數。
如:我們在編譯代碼鏈接庫時,沒有關心庫在哪?這個就是環境變量在幫助編譯器查找。

常見環境變量

  1. PATH:命令搜索路徑
  2. HOME:指定用戶的主工作目錄
  3. HISTSIZE: 保存歷史命令的記錄條數
  4. SHELL:當前shell,通常是/bin/bash

    常用命令
    echo $name :name是環境變量名稱,查看環境變量方法。
    env: 查看所有環境變量
    export:(重點)設置一個環境變量

    在linux下設置環境變量PATH值

    有三種:
    1)設置當前進程的PATH,也就是在當前終端窗口有效,如果重新打開終端又回到以前。在命令行輸入 export PATH=$PATH:路徑
    2)設置用戶環境變量(linux是多用戶多任務)設置完成就可以在改用戶下是永久的。要到用戶的~/.bash_profile
    添加 export PATH=$PATH:路徑
    3)設置全局系統環境變量,到/etc/profile文件中添加。

    通過系統調用來獲取環境變量

    getenv講解
    可以通過代碼調用系統調用來獲取某個環境變量。

    
    #include <stdio.h>
    
    
    #include <stdlib.h>
    
    int main()
    {
     printf("%s\n", getenv("PATH"));
     return 0;
    }

    獲取環境變量PATH的值

如有誤,還望指正,謝謝!

發佈了74 篇原創文章 · 獲贊 35 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章