日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

Linux系统-进程概念

發(fā)布時間:2023/12/10 linux 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Linux系统-进程概念 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

Linux進程概念

  • 零、前言
  • 一、馮諾依曼體系結(jié)構(gòu)
  • 二、操作系統(tǒng)
  • 三、進程
    • 1、描述進程-PCB
    • 2、查看進程
    • 3、獲取進程標示符
    • 4、創(chuàng)建進程-fork()
    • 5、進程狀態(tài)
    • 6、僵尸進程
    • 7、孤兒進程
    • 8、進程優(yōu)先級
    • 9、環(huán)境變量
      • 1)測試PATH
      • 2)測試HOME
      • 3)如何獲取環(huán)境變量
      • 4)命令行變量

零、前言

本章主要講解操作系統(tǒng)的一些基礎(chǔ)概念知識,為進程的學習做鋪墊

一、馮諾依曼體系結(jié)構(gòu)

  • 概念:

馮諾依曼體系結(jié)構(gòu)規(guī)定了硬件上的數(shù)據(jù)流動,而大部分計算機都遵守馮諾依曼體系,如筆記本,服務(wù)器等

  • 示圖:
  • 計算機基本硬件組成:
  • 輸入單元:包括鍵盤, 鼠標,掃描儀, 寫板等

  • 中央處理器(CPU):含有運算器和控制器等

  • 輸出單元:顯示器,打印機等

  • 存儲器:物理內(nèi)存

  • 注:輸入單元和輸出單元統(tǒng)稱外設(shè)

    • 工作原理:

    執(zhí)行程序時,輸入設(shè)備的數(shù)據(jù)先預(yù)加載到存儲器中,通過存儲器將數(shù)據(jù)交給cpu進行處理,cpu再將得到的結(jié)果預(yù)寫入寫回存儲器,最后再由存儲器將結(jié)果刷新到輸出設(shè)備上

    • 注意:
  • 不考慮緩存情況CPU能且只能對內(nèi)存進行讀寫,不能訪問外設(shè)(輸入或輸出設(shè)備)

  • 外設(shè)(輸入或輸出設(shè)備)要輸入或者輸出數(shù)據(jù),也只能寫入內(nèi)存或者從內(nèi)存中讀取

  • 所有設(shè)備都只能直接和內(nèi)存打交道

    • 示例:登錄上qq開始和某位朋友聊天的數(shù)據(jù)的流動過程
  • 你的電腦:輸入設(shè)備鍵盤將數(shù)據(jù)寫到內(nèi)存,內(nèi)存再將數(shù)據(jù)給CPU,CPU得到結(jié)果再將數(shù)據(jù)寫入內(nèi)存,最后內(nèi)存將數(shù)據(jù)刷新到網(wǎng)卡

  • 朋友的電腦:輸入設(shè)備網(wǎng)卡將數(shù)據(jù)寫到內(nèi)存,內(nèi)存再將數(shù)據(jù)給CPU,CPU得到結(jié)果再將數(shù)據(jù)寫入內(nèi)存,最后內(nèi)存將數(shù)據(jù)刷新到顯示器上

    • 為什么運行程序必須先加載到內(nèi)存:

    這是即是馮諾依曼體系結(jié)構(gòu)規(guī)定的,也是由于存儲器分級的原因?qū)е碌?/p>

    • 示圖:存儲器層次結(jié)構(gòu)
  • 內(nèi)存比較便宜速度慢,CPU速度快但是貴,為了平衡速度與經(jīng)濟CPU一般不會太大,所以CPU不能直接存儲數(shù)據(jù)

  • 對于外設(shè)的輸入輸出效率會更慢,如果直接和CPU溝通會導(dǎo)致整個程序變得遲緩,所以由內(nèi)存作為中間者和所有設(shè)備進行直接溝通

  • 二、操作系統(tǒng)

    • 概念:

    任何計算機系統(tǒng)都包含一個基本的程序集合,稱為操作系統(tǒng)(OS)

    • 操作系統(tǒng)包括:
  • 內(nèi)核(進程管理,內(nèi)存管理,文件管理,驅(qū)動管理)

  • 其他程序(例如函數(shù)庫, shell程序等等)

    • 設(shè)計OS的目的:
  • 與硬件交互,管理所有的軟硬件資源

  • 為用戶程序(應(yīng)用程序)提供一個良好的執(zhí)行環(huán)境

  • 注:OS需要保護系統(tǒng)軟硬件,所以它對任何用戶都不信任,需要通過OS才能訪問系統(tǒng)軟硬件

    • 定位:

    操作系統(tǒng)也被稱作進行軟硬件資源管理的軟件

    • 如何理解 “管理”:
  • 操作系統(tǒng)作為管理者,主要做事情決策

  • 而操作系統(tǒng)之下的驅(qū)動作為執(zhí)行者,進行執(zhí)行操作系統(tǒng)的決定

  • 最后的底層硬件則是一個被管理的角色

    • 示圖:
    • 怎么進行管理:
  • 描述:先對被管理者進行描述,將其屬性數(shù)據(jù)獲取(數(shù)據(jù)寫到struct結(jié)構(gòu)體中)

  • 組織:用鏈表或其他高效的數(shù)據(jù)結(jié)構(gòu)進行管理數(shù)據(jù)(結(jié)構(gòu)體),也就是對數(shù)據(jù)的操作達到管理的效果

    • 系統(tǒng)調(diào)用和庫函數(shù)概念:
  • 在開發(fā)角度,操作系統(tǒng)對外會表現(xiàn)為一個整體,但是會暴露自己的部分接口,供上層開發(fā)使用,這部分由操作系統(tǒng)提供的接口,叫做系統(tǒng)調(diào)用

  • 系統(tǒng)調(diào)用在使用上功能比較基礎(chǔ),但對用戶的要求相對也比較高,所以開發(fā)者對部分系統(tǒng)調(diào)用進行適度封裝,從而形成庫,利于更上層用戶或者開發(fā)者進行二次開發(fā)

  • 三、進程

    • 概念:
  • 進程是程序的一個執(zhí)行實例,從內(nèi)核的角度上看進程是擔當分配系統(tǒng)資源(CPU時間,內(nèi)存)的實體

  • 即進程=程序+內(nèi)核的PCB

  • 1、描述進程-PCB

    • 概念:
  • 進程信息被放在一個叫做進程控制塊的數(shù)據(jù)結(jié)構(gòu)中,可以理解為進程屬性的集合;在Linux中描述進程的結(jié)構(gòu)體叫做task_struct

  • Linux操作系統(tǒng)下的PCB是: task_struct-PCB的一種,task_struct是Linux內(nèi)核的一種數(shù)據(jù)結(jié)構(gòu),它會被裝載到RAM(內(nèi)存)里并且包含著進程的信息

    • task_ struct內(nèi)容分類:
    標示符: 描述本進程的唯一標示符,用來區(qū)別其他進程 狀態(tài): 任務(wù)狀態(tài),退出代碼,退出信號等 優(yōu)先級: 相對于其他進程的優(yōu)先級 程序計數(shù)器: 程序中即將被執(zhí)行的下一條指令的地址 內(nèi)存指針: 包括程序代碼和進程相關(guān)數(shù)據(jù)的指針,還有和其他進程共享的內(nèi)存塊的指針 上下文數(shù)據(jù): 進程執(zhí)行時處理器的寄存器中的數(shù)據(jù)[休學例子,要加圖CPU,寄存器 //當多個程序需要同時被執(zhí)行,而一個程序有執(zhí)行的時間片,達到時間需要切換程序,切換到恢復(fù)的過程就需要上下文數(shù)據(jù)發(fā)揮作用,達到無縫切換的效果 I/O狀態(tài)信息: 包括顯示的I/O請求,分配給進程的I/ O設(shè)備和被進程使用的文件列表 記賬信息: 可能包括處理器時間總和,使用的時鐘數(shù)總和,時間限制,記賬號等 其他信息

    注:運行在系統(tǒng)里的進程都以task_struct鏈表的形式存在內(nèi)核里

    2、查看進程

  • 進程的信息可以通過 /proc 系統(tǒng)文件夾查看
    • 示例:
  • 大多數(shù)進程信息同樣可以使用top和ps這些用戶級工具來獲取
    • 示例:

    3、獲取進程標示符

    • 系統(tǒng)調(diào)用函數(shù):
  • 使用getpid()系統(tǒng)調(diào)用函數(shù)獲取當前進程id(PID)

  • 使用getppid()系統(tǒng)調(diào)用函數(shù)獲取當前進程的父進程id(PPID)

  • 注:getpid()和getppid()函數(shù)需要包含頭文件unistd.h

    • 示例:
    #include <stdio.h> #include <unistd.h>int main() {printf("pid: %d\n", getpid());printf("ppid: %d\n", getppid());return 0; }
    • 結(jié)果:

    4、創(chuàng)建進程-fork()

    • fork()功能:

    為當前進程創(chuàng)建子進程,父子進程代碼共享,數(shù)據(jù)各自開辟空間私有一份(采用寫時拷貝:進行寫入時觸發(fā)拷貝)

    • fork()返回值:
  • 對于父進程,如果創(chuàng)建成功返回子進程的pid,否則返回負數(shù)

  • 對于子進程返回0(成功創(chuàng)建)

    • 注意:
  • 對子進程返回0,是因為子進程只有一個父進程,可以直接找到對應(yīng)父進程

  • 對父進程返回子進程pid的意義是可以在父進程里直接得到子進程ID(可能有多個子進程),對某個子進程進行操作和管理

  • 注:fork返回類型是pid_t,需要包含頭文件 sys/types.h

    • 示例:
    #include <stdio.h> #include <sys/types.h> #include <unistd.h> int main() {pid_t ret = fork();printf("hello proc : %d!, ret: %d\n", getpid(), ret);sleep(1);return 0; }
    • 結(jié)果:
    • 父子進程分流執(zhí)行:

    我們創(chuàng)建子進程的意義是為了與父進程進行不同任務(wù),因為父子進程的代碼共享,所以我們采用分支結(jié)構(gòu)進行分流執(zhí)行程序

    • 示例:
    #include <stdio.h> #include <sys/types.h> #include <unistd.h> int main() {int ret = fork();if(ret < 0){perror("fork");return 1;}else if(ret == 0){ //childprintf("I am child : %d!, ret: %d\n", getpid(), ret);}else{ //fatherprintf("I am father : %d!, ret: %d\n", getpid(), ret);}sleep(1);return 0; }
    • 結(jié)果:
    • 為什么ret有兩個返回值:

    fork()函數(shù)在return的前一刻,其主體任務(wù)全部完成,也就是子進程成功創(chuàng)建,此時父子進程代碼共享,數(shù)據(jù)各有一份(寫時拷貝),在返回時發(fā)生寫實拷貝,對于父進程的ret則是返回的子進程的pid,對于子進程的ret則是返回的0

    5、進程狀態(tài)

    進程有不同狀態(tài),一個進程可以有幾個狀態(tài)

    注:在Linux內(nèi)核里,進程有時候也叫做任務(wù)

    • 狀態(tài)在kernel源代碼里定義 :
    /* * The task state array is a strange "bitmap" of * reasons to sleep. Thus "running" is zero, and * you can test for combinations of others with * simple bit tests. */ static const char * const task_state_array[] = {"R (running)", /* 0 */"S (sleeping)", /* 1 */"D (disk sleep)", /* 2 */"T (stopped)", /* 4 */"t (tracing stop)", /* 8 */"X (dead)", /* 16 */"Z (zombie)", /* 32 */ };
    • 解釋:
  • R運行狀態(tài)(running):并不意味著進程一定在運行中,它表明進程要么是在運行中要么在運行隊列里(可以被調(diào)度)

  • S睡眠狀態(tài)(sleeping):意味著進程在等待事件完成(這里的睡眠有時候也叫做可中斷睡眠,即淺睡眠)

  • D磁盤休眠狀態(tài)(Disk sleep):有時候也叫不可中斷睡眠狀態(tài),在這個狀態(tài)的進程通常會等待IO的結(jié)束(不能被進程殺死,此外還包括僵尸進程)

  • T停止狀態(tài)(stopped):可以通過發(fā)送 SIGSTOP 信號給進程來停止(T)進程,這個被暫停的進程可以通過發(fā)送 SIGCONT 信號讓進程繼續(xù)運行

  • X死亡狀態(tài)(dead):這個狀態(tài)只是一個返回狀態(tài),你不會在任務(wù)列表里看到這個狀態(tài)(非常快結(jié)束)

  • t (tracing stop)狀態(tài):表示進程追蹤狀態(tài),即進程在調(diào)試中停下來的一個狀態(tài)(有些內(nèi)核版本沒有該狀態(tài))

    • 示圖:
    • 查看狀態(tài)指令基本格式及選項:
    ps aux / ps axj :查看系統(tǒng)中所有的進程 ps -la :查看基礎(chǔ)進程 a:顯示一個終端的所有進程,除會話引線外 u:顯示進程的歸屬用戶及內(nèi)存的使用情況 x:顯示沒有控制終端的進程 -l:長格式顯示更加詳細的信息 -e:顯示所有進程
    • 效果:

    6、僵尸進程

    • 概念:
  • 僵死狀態(tài)(Zombies)是一個比較特殊的狀態(tài)。當進程退出并且父進程(使用wait()系統(tǒng)調(diào)用)沒有讀取到子進程退出的返回代碼時就會產(chǎn)生僵死(尸)進程

  • 僵死進程會以終止狀態(tài)保持在進程表中,并且會一直在等待父進程讀取退出狀態(tài)代碼

  • 即只要子進程退出,父進程還在運行,但父進程沒有讀取子進程狀態(tài),子進程進入Z狀態(tài)

    • 示例:
    #include <stdio.h> #include <stdlib.h> int main() {pid_t id = fork();if(id < 0){perror("fork");return 1;}else if(id > 0){ //parentprintf("parent[%d] is sleeping...\n", getpid());sleep(30);}else{printf("child[%d] is begin Z...\n", getpid());sleep(5);exit(EXIT_SUCCESS);}return 0; }
    • 結(jié)果:
    • 為什么有僵尸進程:

    創(chuàng)建進程是用來執(zhí)行任務(wù)的,而進程的退出狀態(tài)保存了任務(wù)執(zhí)行的狀態(tài)信息,所以必須被維持下,以此等待父進程獲取其退出信息及任務(wù)狀態(tài),進行下一步打算

    • 僵尸進程的危害:

    父進程如果一直不讀取,那子進程就一直處于Z狀態(tài),而維護退出狀態(tài)本身就是要用數(shù)據(jù)維護,也屬于進程基本信息,所以保存在task_struct(PCB)中,即一直不回收僵尸進程可能造成內(nèi)存資源的浪費,直到被回收后才能釋放其空間

    7、孤兒進程

    • 概念:

    父進程先退出,子進程就稱之為“孤兒進程”,而孤兒進程會被1號 init 進程(系統(tǒng))領(lǐng)養(yǎng),最后由 init 進程回收

    • 示例:
    #include <stdio.h> #include <unistd.h> #include <stdlib.h> int main() {pid_t id = fork();if(id < 0){perror("fork");return 1;}else if(id == 0){//childprintf("I am child, pid : %d\n", getpid());sleep(10);}else{//parentprintf("I am parent, pid: %d\n", getpid());sleep(3);exit(0);}return 0; }
    • 結(jié)果:

    8、進程優(yōu)先級

    • 概念:
  • cpu資源分配的先后順序,就是指進程的優(yōu)先權(quán)(priority),優(yōu)先權(quán)高的進程有優(yōu)先執(zhí)行權(quán)利

  • 配置進程優(yōu)先權(quán)對多任務(wù)環(huán)境的linux很有用,可以改善系統(tǒng)性能

  • 還可以把進程運行到指定的CPU上,以此可以大大改善系統(tǒng)整體性能

    • 權(quán)限和優(yōu)先級的區(qū)別:
  • 權(quán)限是能不能執(zhí)行的問題
  • 優(yōu)先級是能執(zhí)行,但是是先執(zhí)行還是后執(zhí)行
  • 本身是因為資源有限,需要競爭獲取資源,才提出優(yōu)先級
    • 查看優(yōu)先級:

    使用 ps –l 命令

    • 示例:
    • 解釋:
  • UID : 代表執(zhí)行者的身份

  • PID : 代表這個進程的代號

  • PPID :代表這個進程是由哪個進程發(fā)展衍生而來的,亦即父進程的代號

  • PRI :代表這個進程可被執(zhí)行的優(yōu)先級,其值越小越早被執(zhí)行

  • NI :代表這個進程的nice值

    • PRI and NI:
  • PRI即進程的優(yōu)先級,或者通俗點說就是程序被CPU執(zhí)行的先后順序,此值越小進程的優(yōu)先級別越高

  • NI即nice值,其表示進程可被執(zhí)行的優(yōu)先級的修正數(shù)值

  • 所以最終的優(yōu)先級:PRI(new)=PRI(old)+nice

    注:這里的PRI(old)可以理解為一直是基準值80

  • 當nice值為負值的時候,那么該程序?qū)?yōu)先級值將變小,即其優(yōu)先級會變高,則其越快被執(zhí)行

  • 所以調(diào)整進程優(yōu)先級,在Linux下就是調(diào)整進程nice值

  • nice其取值范圍是 -20至19 一共40個級別

    • PRI vs NI:
  • 進程的nice值不是進程的優(yōu)先級,但是進程nice值會影響到進程的優(yōu)先級變化

  • 可以理解nice值是進程優(yōu)先級的修正修正數(shù)據(jù)

    • 修改nice值:

    先使用top命令,進入top后按“r”–>輸入進程PID–>輸入nice值

    • 示例:
    • 為什么PRI要有基準值以及NI具有范圍:
  • 避免過高或者過低的優(yōu)先級出現(xiàn),保證可控并且競爭的相對公平,提高效率

  • 便于運算,不用再讀取優(yōu)先級信息,并且實現(xiàn)簡單

    • 進程退出CPU的可能:
  • 優(yōu)先級更高的進程搶占了CPU

  • 該進程時間片到了(多進程運行)

  • 注:進程讓出或者占領(lǐng)CPU資源時,就需要進行保存或者恢復(fù)進程的上下文數(shù)據(jù)

    • 其他概念:
  • 競爭性: 系統(tǒng)進程數(shù)目眾多,而CPU資源只有少量,甚至1個,所以進程之間是具有競爭屬性的。為了高效完成任務(wù),更合理競爭相關(guān)資源,便具有了優(yōu)先級

  • 獨立性: 多進程運行,需要獨享各種資源,多進程運行期間互不干擾

  • 并行: 多個進程在多個CPU下分別,同時進行運行,這稱之為并行

  • 并發(fā): 多個進程在一個CPU下采用進程切換的方式,在一段時間之內(nèi),讓多個進程都得以推進,稱之為并發(fā)

  • 9、環(huán)境變量

    • 概念:
  • 環(huán)境變量(environment variables)一般是指在操作系統(tǒng)中用來指定操作系統(tǒng)運行環(huán)境的一些參數(shù)

  • 環(huán)境變量通常具有某些特殊用途,還有在系統(tǒng)當中通常具有全局特性(可以被子進程繼承)

    • 示例:

    我們在編寫C/C++代碼的時候,在鏈接的時候,從來不知道我們的所鏈接的動態(tài)靜態(tài)庫在哪里,但是照樣可以鏈接成功,生成可執(zhí)行程序,原因就是有相關(guān)環(huán)境變量幫助編譯器進行查找

    • 常見環(huán)境變量:
  • PATH : 指定命令的搜索路徑

  • HOME : 指定用戶的主工作目錄(即用戶登陸到Linux系統(tǒng)中時,默認的目錄)

  • SHELL : 當前Shell,它的值通常是/bin/bash

    • 查看環(huán)境變量:

    echo $NAME //NAME:你的環(huán)境變量名稱

    • 示例:

    1)測試PATH

    注:以PATH為例,展現(xiàn)環(huán)境變量的作用

    • 示例:簡單寫個程序
    #include <stdio.h> int main() {printf("hello world!\n");return 0; }
    • 結(jié)果:
    • 引入:

    為什么有些指令可以直接執(zhí)行,不需要帶路徑,而我們的二進制程序需要帶路徑才能執(zhí)行?

    • 原因:
  • 執(zhí)行程序前,系統(tǒng)會在特定路徑下查找對應(yīng)程序

  • 而PATH的作用是輔助系統(tǒng)進程指令查找,PATH變量儲存的就是可能存在指令或者程序的路徑

    • 示圖:

    注:其實程序,命令,指令,可執(zhí)行程序等等都是一個概念

    • 如何將程序像指令一樣執(zhí)行(不帶路徑執(zhí)行):
  • 將我們的程序所在路徑加入環(huán)境變量PATH當中
  • 使用指令 export PATH=$PATH:path(程序所在路徑)

    • 示例:

    注:該添加方法只在當前有用,退出Linux后則會恢復(fù),想永久設(shè)置則需在環(huán)境變量文件中進行添加

  • 將程序拷貝到PATH變量中的某個路徑中
    • 示例:

    2)測試HOME

    • 對比效果:root和普通用戶執(zhí)行 echo $HOME
    • 解釋:

    一個用戶默認所處的路徑是由環(huán)境變量HOME決定的,環(huán)境變量home是決定用戶所處的主工作目錄的

    • 和環(huán)境變量相關(guān)的命令:
  • echo: 顯示某個環(huán)境變量值

  • export: 設(shè)置一個新的環(huán)境變量

  • env: 顯示所有環(huán)境變量

  • unset: 清除環(huán)境變量

  • set: 顯示本地定義的shell變量和環(huán)境變量

    • 環(huán)境變量的組織方式:
    • 解釋:

    每個程序都會收到一張環(huán)境表,環(huán)境表是一個字符指針數(shù)組,每個指針指向一個以’\0’結(jié)尾的環(huán)境字符串

    3)如何獲取環(huán)境變量

  • 命令行第三個參數(shù)
    • 示例:
    #include <stdio.h> int main(int argc ,char *argv[] ,char* env[])//命令行參數(shù)個數(shù)、命令行參數(shù)、環(huán)境變量 {int i = 0;for(; env[i]; i++) //遍歷env指針數(shù)組打印環(huán)境變量的值{printf("env[%d]:%s\n", i, env[i]); }return 0; }
    • 結(jié)果:
  • 通過第三方變量environ獲取
    • 示例:
    #include <stdio.h> int main(int argc, char *argv[]) {extern char **environ;int i = 0;for(; environ[i]; i++){printf("%s\n", environ[i]);}return 0; }
    • 注意:

    libc中定義的全局變量environ指向環(huán)境變量表,environ沒有包含在任何頭文件中,所以在使用時要用extern聲明

  • 通過系統(tǒng)調(diào)用獲取或設(shè)置環(huán)境變量
    • 示例:
    #include <stdio.h> #include <stdlib.h> int main() {printf("PATH:%s\n", getenv("PATH"));return 0; }
    • 結(jié)果:

    注:常用getenv和putenv函數(shù)來訪問特定的環(huán)境變量

    4)命令行變量

    • 在命令行中,我們可以定義兩種變量:
  • 本地變量:只能夠在當前shell命令行解釋器內(nèi)被訪問,不能被子進程繼承
  • ? 注:在命令行運行的指令,它的父進程都是bash

  • 環(huán)境變量:可以被子進程繼承
    • 示例:

    總結(jié)

    以上是生活随笔為你收集整理的Linux系统-进程概念的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。