進程

一.操作系統
     1.操作系統是應用程序和硬件之間的插入的一層軟件,所有應用程序對硬件的操作都要通過操作系統。任何計算機都包含一個基本的程序集合,稱爲操作系統
    2. 內核: 是操作系統最基本的部分,主要負責管理系統資源( 通過進程間通信機制及系統調用,應用進程可間接控制所需的硬件資源(特別是處理器及IO設備
     3.操作系統的目的是與硬件交互,管理所有的硬件資源,同時爲用戶程序(應用)提供良好的執行環境
     4.Linux操作系統


二、進程
     進程是操作系統對一個正在運行的程序的一種抽象,擔當分配系統資源(cpu時間、內存)的實體
     進程的兩個基本元素時程序代碼(可能被執行相同程序的其他進程共享)和代碼相關聯的數據集,進程是一種動態描述。(進程在內存中因一些策略或者調度需求,處於各種狀態)
    
     1.進程的描述
     廣義上,所有進程的信息被放在一個叫做進程控制塊(pcb)的數據結構中,可以理解爲進程屬性的集合。
     
     2.進程控制塊
     每個進程在內核中都有一個進程控制塊(PCB)來維護進程相關信息。在Linux內核的進程控制塊是task_struct結構體
        ①task_struct是什麼
          task_struct是 Linux的一種數據結構,它被裝載到RAM裏幷包含進程的信息,每個進程都把它的信息放到task_struct裏。
        ②task_struct包含什麼
          標識符:描述一個進程的唯一標識符,用來區別其他進程
          狀態:任務狀態,退出代碼,退出信號等
          優先級:相對於其他進程的優先級
          程序計數器:程序中即將被執行的下一條指令的地址
          內存指針:包括程序代碼和進程相關數據的指針,還有和其他進程共享的內存塊指針(持找到被切出去的線程 )
          上下文數據:進程執行時處理器的寄存器中的數據(保存切換的線程信息 )
          I/O狀態信息:包括顯示I/O請求,分配給進程I/O設備和進程使用的文件列表
          記賬信息:包括處理器的時間總和,使用時鐘數總和,時間限制,記賬號等
    
     應用程序就是二進制文件,進程將程序加載到內存,操作系統爲該進程分配整套數據結構,所有運行的在操作系統裏的進程都以task_struct鏈表的形式存在內核裏

     3.進程標示符
     進程id(PID)
     父進程id(PPID )
     
     4.進程位置
     1.進程內存映像
          Linux下的C程序生成主要分爲四個步驟組成
          預編譯-->編譯-->彙編-->鏈接
          編譯器gcc經過預編譯、編譯。彙編3個步驟將源程序文件轉換成目標文件,如果程序有多個目標文件或者程序中使用了庫函數,則編譯器還需要將所有的目標文件以及庫文件連接起來,最後生成可執行文件。
          程序轉爲進程通常需要以下步驟
          *內核爲該進程分配進程標識符PID以及其他所需資源
          *內核將程序讀入內存,將程序分配內存空間
          *內核爲該程序保存PID自己相應的狀態信息,把進程放到運行隊列中等待執行,程序轉化爲進程之後就可以被操作系統的跳讀程序執行
          
     內存映像是指內核在內存中如何存放可執行程序文件。將程序轉化爲進程的過程中,操作系統將可執行程序從硬盤複製到內存中
     進程內存佈局分爲四個不同的段
     *文本段,包含程序源指令,是共享和只讀的
     *數據段,包含靜態變量,在程序開始執行前,內核將此段中的數據初始化爲0或空指針
     *堆,動態開闢的空間
     *棧,動態增長與收縮的段,保存本地變量
     

     2.進程映像的位置依賴於使用的內存管理方案
     3.可執行程序與進程內存映像的不同之處
        a.可執行程序位於磁盤而內存映像位於內存
        b.可執行程序沒有堆棧,因爲程序被加載到內存中才會分配堆棧
        c.可執行程序雖然也有未初始化數據段但它並不被存儲位於磁盤中可執行文件中
        d.可執行程序時靜態的,不變的,而內在映像隨着程序的執行時動態變化的,比如數據段隨着程序的執行要存儲新的變量值,棧在函數調用時也是不斷變化的
    
      5環境變量
     環境變量是一組字符串,如下圖
     
     libc中定義的全局變量environ指向環境變量表,environ中沒有包含任何頭文件,所以在使用時用extern聲明。
     父進程的環境變量和shell環境變量是相同的,父進程在調用fork創建子進程時會把自己的環境變量也複製給子進程

     6.進程狀態
     R(running)     運行,表明進程要麼是在運行中要麼是在運行隊列裏
     S(sleeping)     睡眠,表明進程在等待事件完成(是可中斷睡眠)
     D(disk sleep)  不可中斷睡眠,磁盤休眠狀態,這個狀態的進程通常需要等IO的結束
     T(stopped)     停止,可以通過發送SIGSTOP來停止進程,這個進程可以通過發送SIGCONT信號讓進程來繼續運行
          kill -SIGSTOP<pid>
          kll -SIGCONT<pid>

     t(tracing stop)
     X(dead)       死亡狀態,是內核運行的do_exit()函數返回狀態,這個狀態僅是一個返回狀態,不會再任務列表裏看到這個狀態
     Z(zomie)     殭屍進程狀態,當進程在父進程沒有使用wait()或waitip系統調用,沒有讀取到子進程退出的返回代碼時會產生殭屍狀態,殭屍進程會終止狀態保持在進程表中,若父進程一直存在兒不調用wait,該殭屍進程無法回收,等到父進程退出後進程被init回收
          讓其他進程獲取到這個進程結束的原因,這個殭屍進程是進程已經不在了代碼不再執行,不過pcb還在(保存狀態及原因)
     
     7.進程優先級
     進程cpu資源分配即進程優先級,優先級高的進程有優先執行的權利,配置進程優先權對多任務環境Linux十分重要,可以改善系統性能,還可以把進程運行到指定的cpu上,這樣,把不重要的進程安排到某個cpu上,可以大大改善整體性能
     
     UID:代表執行者身份
     PID:代表進程代號
     PPID:這個進程是由哪個進程發展衍生來的,即父進程代號
     PRI:這個進程可被執行的優先級,其值越小越早被執行
     NI:代表進程的nice值,表示進程可被執行的優先級的修正數值,加入nice值後,PRI(new)=PRI+nice,這樣,當nice值爲負值時,程序的優先級值變小,優先級變高,越快被執行
        1.進程優先級修改  nice和renice修改
          ①一開始執行程序就指定nice值
          nice -n -5 ./test
          ②調整已存在進程的nice:renice
          renice -5 -p 5200    將PID爲5200的進程nice值設爲-5
          ③用top命令更改以存在進程的nice
          top
          #進入top後按 r -->輸入進程PID-->輸入nice值
ps:
     權限:權限不同於優先級,優先級表示獲取資源的能力大小,而資源表示有沒有獲取資源的能力
          getlimit和setlimit函數用於獲取或設置進程的資源限制,資源限制通常是由進程0建立的,有每個後序進程繼承,更改資源限制時,注意
          ①進程的軟限制值只能小於或等於硬限制值
          ②任意進程都可以降低其硬件限制值,但是它必須大於或等於其軟限制值,這種操作對於普通用戶是不可逆的
          ③只有超級用戶進程可以提高硬限制值
     8.創建進程
     創建一個進程有兩種方法,fork()和execve(),它們都是系統調用,但是運行方式不同
        ①fork():要創建一個子進程可以執行fork()系統調用,然後子進程得到父進程的數據段、棧段和堆區的一份拷貝,子進程可以修改這些內存段,但是文本段是子進程和父進程共享的內存段,不能被子進程修改,創建成功子進程返回1,父進程返回子進程PID,創建失敗返回-1
        ②execve():創建一個新進程,這個系統調用會銷燬所有的內存段去重新創建一個新的內存段。execve()需要一個可執行文件或者腳本作爲參數。
          fork和execve創建的進程都是運行進程的子進程

          孤兒進程:一個父進程退出,然而它的一個或多個子進程還在運行,那麼這個子進程將成爲孤兒進程,孤兒進程將被init進程(進程號爲1)所收養,並由init進程對它們完成狀態收集工作
    
     9.進程終止
     進程終止有8種,
     1.main函數返回,return
     在除了main函數以外的函數不表示進程退出,當main函數調用return表示進程退出
     2,exit
     _exit和_Exit可以立即進入內核,exit需要先做一些清理(調用執行各終止處理程序,關閉所有標準IO流),再進入內核,三個函數所帶的整形參數稱爲終止狀態或退出狀態,如果:①調用這些函數不帶參數②main函數中的return語句無返回值③main函數沒有申明返回類型爲整形,則進程終止狀態是未定義的。main函數返回一個整形值與該值調用exit是等價的
     3.atexit--->進程退出時調用
發佈了28 篇原創文章 · 獲贊 1 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章