進行概念詳解 多線程上篇(二)

操做系統是程序與硬件交互的中間層,現代操做系統將程序的一次執行抽象爲進程和線程的概念。
進程做爲資源分配的基本單位,線程做爲執行的基本單位。
進程和線程其實就是操做系統程序自己實現控制一個程序運行的數據項描述
全部的程序都是面向語言進行開發的,而語言自己是面向操做系統的,線程是操做系統對程序一次運行的抽象
因此,全部的多線程編程模型,必然聽從操做系統的大邏輯,必然是符合操做系統的對線程的抽象概念,操做系統在抽象之上提供了API供應用程序調用
簡言之,應用程序的底層是藉助於操做系統來完成多線程編程模型的,因此怎麼可能逾越系統這一根本?
本篇對操做系統中線程進程相關概念進行簡單介紹

進程

在好久好久以前的串行執行時,程序按順序加載到計算機中並運行,程序獨佔計算機的全部資源
程序具備順序性,封閉性和可重現性
多道程序出現以後,程序須要併發的執行,計算機的資源是共享的,而再也不是某一程序運行後獨享
因此再也不是順序的,而是間斷的,也再也不是封閉,也再也不具備可重現性
image_5c56750f_433
仍是以作飯爲例,當只有你一我的使用廚房時,你能夠隨便;
可是當多我的共享時,若是你還把你本身切了一半的菜扔到那邊,可能會被扔掉,可能會被用掉,固然也可能沒事。
爲了解決程序併發執行的問題,進程的概念被抽象出來,其實就至關於「一個廚房使用規章」被制定出來
因此說進程和線程就是操做系統用來管理維護一個程序的運行於切換而設計出來的一個概念,而後經過各類數據結構以及值等實現描繪出來

進程實體

一個程序的運行主要下面幾個部分的數據
  • 進程自己的信息(如今誰在用廚房?如今盆盆罐罐都被你放了什麼?)
  • 可執行的代碼是哪些?(菜譜步驟是什麼?)
  • 程序運行所須要的數據是什麼?(食材是什麼?佐料又是什麼?)
程序段、數據段、PCB(Process Control Block)三部分構成了進程實體
image_5c567510_705

進程特徵

程序的併發運行與以前的串行順序運行有了很大的變化,主要有下面幾個特徵
  • 動態性
  • 併發性
  • 獨立性
  • 異步性
image_5c567510_5e4b
 

進程狀態

基本狀態

多人輪流使用廚房時,某一時刻的你究竟是作完飯了?仍是還在排隊?仍是正在作?你會有一個狀態用來表述你如今的這種狀況
對於進程也有狀態的概念
最基本的狀態包括:
  • 建立
  • 就緒
  • 執行
  • 阻塞
  • 終止
其中核心是:就緒、執行、阻塞
image_5c567510_26b3
 
基本的狀態切換以下
image_5c567510_5a7d
狀態轉變簡介:
進程建立後,會建立PCB,以及相關的必須信息,而後就進入就緒狀態,等待CPU的調度
一旦CPU對該進程調度執行,也就是該進程得到了時間片,那麼就會進行執行
當時間片用完以後,若是任務尚未結束,那麼就須要繼續等待(好比你作飯須要5小時,然而每一個人只容許2小時,若是2小時你作不完,你必須讓別人先作,你從新排隊來)
若是一個正在執行的程序遇到了IO請求,這一般是比較耗時的,進程會進入阻塞狀態
進入阻塞狀態的進程一旦得到了想要的結果,好比IO完成,那麼就再次進入就緒狀態,等待CPU的臨幸

掛起狀態

有些系統中,還會有掛起狀態,可能系統須要讓正在執行的程序暫停下來,也多是資源不足了,將某些不重要的進程暫停。
掛起是更完全的暫停,能夠認爲掛起是「暫時被淘汰出內存的進程」
阻塞狀態得到資源後會進入就緒狀態,而一旦掛起,除非解除這個狀態,不然他將一直暫停,被拋出運行以外
阻塞是由於某些緣由暫時不能被執行,掛起是直接將你暫停
當你作飯時等待水燒開,這就是阻塞,而若是是老大說咱們幾我的先來,因而他們幾個輪流使用,而後你站門口看着,這就是掛起
image_5c567510_710c
包含掛起狀態的系統基本狀況如上圖所示
就緒狀態掛起後稱之爲靜態就緒,阻塞狀態掛起後稱之爲靜態阻塞,掛起後的狀態不可以直接轉換到執行狀態
活動狀態通過掛起轉換爲靜止狀態,靜止狀態通過激活轉換爲活動狀態
活動就緒與靜止就緒經過掛起和激活轉換;活動阻塞與靜止阻塞經過掛起和激活轉換;
活動就緒的狀態通過進程調度得到CPU時間片,進入執行狀態,執行狀態遇到請求IO等阻塞操做進入活動阻塞狀態,活動阻塞狀態IO完成將會進入活動就緒狀態,繼續等待被CPU臨幸,如上圖藍色三角區域
 
看起來複雜其實也很好理解,前提是要理解掛起的含義
好比資源不充足時,將一些不重要的進程暫時掛起,掛起是真正的暫停執行,是一種主動式的管理,阻塞則是被動的,掛起也意味着置換到外存中,而不是內存中
無論是活動阻塞仍是活動就緒,他們都在內存中,具有了相關條件,IO完成或者得到CPU時間片,就能夠進行執行
掛起(靜止)狀態,靜止阻塞仍是靜止就緒,他們都是外存中,並不可以執行,他們還須要一個載入到內存的過程
一個靜止阻塞的狀態就至關於在外存中等待一個事件的完成,事件完成後,進入靜止就緒狀態,他此時仍是不會獲得CPU的調度,激活後纔有機會獲得CPU臨幸
存在掛起狀態的系統,通過建立後,可能進入活動就緒,也可能進入靜止就緒,並非必定進入活動就緒,而後再被掛起
在當前系統的性能和內存的容量均容許的狀況下,完成對進程建立的必要操做後,相應的系統進程將進程的狀態轉換爲活動就緒狀態
考慮到系統當前資源情況和性能要求,並不分配給新建進程所需資源,主要是主存資源,相應的系統進程將進程狀態轉爲靜止就緒狀態

終止狀態的轉換

終止狀態一般是從執行狀態進行轉換,通常狀況下無論一個什麼狀態的線程,他只有被執行時,纔會可能進入終止狀態
可是,在某些系統中,父進程有權利終止一個子進程,因此說這種狀況下,就可能從阻塞或者就緒直接轉換爲終止狀態

進程控制塊

進程是對於程序執行的抽象描述,那麼進程控制塊,這個對進程的描述,就至關於進程的元數據,用於描述進程自己
儘管實現很複雜,可是咱們應該想象獲得,操做系統內核都是C/C++,畢竟也只是一種編程語言,編程語言對於抽象概念的描述也只能是經過語言自己
因此說,他就是一個數據結構,記錄了用於控制管理進程的各個數據項。
「PCB 中記錄了操做系統所需的、用於描述進程的當前狀況以及控制進程運行的所有信息。
進程控制塊的做用是使一個在多道程序環境下不能獨立運行的程序(含數據),成爲一個能獨立運行的基本單位,一個能與其它進程併發執行的進程。
或者說OS是根據 PCB來對併發執行的進程進行控制和管理的
例如,當OS要調度某進程執行時,要從該進程的 PCB中查出其現行狀態及優先級;
在調度到某進程後,要根據其 PCB 中所保存的處理機狀態信息,設置該進程恢復運行的現場,並根據其 PCB 中的程序和數據的內存始址,找到其程序和數據;
進程在執行過程當中,當須要和與之合做的進程實現同步、通訊或訪問文件時,也都須要訪問 PCB;
當進程因爲某種緣由而暫停執行時,又須將其斷點的處理機環境保存在PCB中。
可見,在進程的整個生命期中,系統老是經過 PCB對進程進行控制的,亦即,系統是根據進程的PCB而不是任何別的什麼而感知到該進程的存在的。
因此說,PCB是進程存在的唯一標誌」《計算機操做系統 第三版》
 
image_5c567510_4ccc
進程控制塊主要包括:
  • 進程標識符
  • 計算機狀態
  • 進程調度信息
  • 進程控制信息
進程用來管理程序運行,對於一個運行中的程序總歸要有個名字,這就是進程標識符;
計算機運行時各個硬件設備寄存器保存的值就是計算機的狀態(如同作飯時廚房盆盆罐罐裏面的東西);
進程有狀態,這些狀態信息主要用來進行調度,也就是安排任務須要的信息(可能你長得好看,就能多一次機會使用廚房);
另外還有一些對進程的控制,好比進程(線程)同步數據、程序地址等
 
在一個系統中,一般可擁有數十個、 數百個乃至數千個 PCB。
爲了能對它們加以有效的管理,應該用適當的方式將這些PCB組織起來。目前經常使用的組織方式有如下兩種。
image_5c567510_7bb2

三座大山

進程做爲操做系統對程序一次運行的抽象描述
進程的基本信息至關於元數據,就好像表結構同樣以及一些必備的數據結構
對於進程的掌控主要有三座大山:
進程控制、進程同步、進程通訊
進程控制:
一個進程從無到有,須要建立,建立以後由於調度而運行,由於撤銷而消亡,須要有人管理他們,進程基本信息好比PCB從哪裏來?都須要有人去作,這部分工做被稱爲進程控制
進程同步:
多進程併發執行,必然可能會出現竟態,好比同時訪問某個共享資源,一個打印機不能同時打印語文和數學,因此必須作好順序的調度,這部分的工做被稱之爲進程同步
進程通訊:
多進程併發運行,如何進行進程間的聯繫,如何傳遞數據?不一樣計算機中的兩個進程又是如何進行數據交互?這部分工做被稱之爲進程通訊
 
若是一個員工是一個進程,進程控制至關於人事、財務部門,負責招聘薪資考勤等。
進程同步至關於項目經理,負責項目中各人員的任務分配調度。
進程通訊就至關於一種工做方式、溝通形式,好比你給我一個SVN標籤號而且告知我意圖,我去庫中檢索指定標籤修改的指定內容,就完成了一個任務的協做。
比喻或許不足夠恰當,僅供我的理解。

總結

進程做爲操做系統對程序執行的抽象,那麼就使用了足夠多的數據項對進程進行描述,全部的信息都是爲了進程的管理、維護、調度、切換等
就好比你用一個數組以及一個棧頂標記來描述一個堆棧,以下圖所示
image_5c567510_739
數組a[]以及變量top就是使用數組對棧這種數據結構進行抽象描述的數據項,對於數據元素操做訪問(入棧、出棧)限制就是規則
進程看似複雜,原理也是如此,操做系統使用多個數據項(數據結構)對程序的執行進行描述,而後定義了一整套的操做邏輯與規則
這就是咱們如今學習的進程的運行原理
經過編碼將設計思路以及運行規則從抽象到具體數據結構以及編碼的實現就完成了進程的實現。
 
操做系統想要管理程序的運行,須要指定一個惟一的標識符,既然放一羣羊,還想對羊進行合理的管理識別,最簡單的辦法就是每隻羊掛個項圈寫上序號。
進程有狀態信息,操做系統負責管理狀態的切換,那麼必然須要記錄進程的狀態信息
既然是輪流分配時間片,就好像去辦理業務,排隊等待同樣,可是無數個場景下都有VIP的存在,進程也是,也有優先級的概念
計算機的程序最終會轉換爲一條條的指令,每一條指令的執行都須要藉助於程序計數器,程序計數器是用於存放下一條指令所在單元的地址的地方,因此想要知道而且記住程序執行的進度位置,還須要掌握程序計數器的值
 
咱們熟悉的x86和arm指令大多都是基於寄存器的(虛擬機VM是基於棧)基於寄存器的架構最明顯的特徵就在於指令的執行要依賴寄存器,如同廚房的盆盆罐罐,裏面裝着運行時的狀態數據、值(比如計算1+2+3+4,1放到a寄存器,2放到b寄存器,add a,b 計算中間結果,這句純屬爲了說明,具體不要較真)   
想要更好地管理進程,那麼必然還會有一些統計信息,好比某進程運行了多久等記錄統計信息
這些重要的信息都保存在進程的PCB中,因此說PCB是進程概念的核心,有了PCB程序纔有併發執行的能力,一般,一般狀況下,建立進程指的就是建立PCB
簡言之,操做系統對進程的抽象就是對於一組數據結構以及操做這些數據結構的規則邏輯的實現。
進程的核心狀態有執行、就緒、阻塞。
就緒就是一切準備穩當,能夠被執行,就差CPU時間片了,在執行過程當中若是時間片用完,那麼仍舊是轉換爲就緒狀態,他什麼都不差,只是被剝奪了時間片
執行狀態下,若是執行不下去了,好比須要等待IO,就會進入阻塞,阻塞必需要等到要等的事情發生纔會解除阻塞,由於他差一個事件的發生和時間片,事件到達就解除阻塞,因此就差時間片了,因此轉換爲就緒狀態
好比你去銀行辦業務,人家手續都帶好了在那邊排隊就是就緒,你身份證沒複印好,就得先複印好身份證再過來排隊,不然即便到你了,你也辦不成
就緒涉及到不少事情要處理,因此爲了更加安全合理,有了建立的狀態,建立就是爲了保障就緒是真的就緒了,也就是檢查你的確各類資料都帶齊全了
終止狀態也是相似爲了更合理安排管理,結束後也有一些事情須要作,好比你把你的資料狀態或者還可能要排隊領取個什麼別的東西,這些都不須要在櫃檯了,在大廳自助或者找大堂經理就行了
進程涉及到各類數據結構,各類規則處理,因此進程很複雜,可是進程又很簡單,就比如單例模式的實現有多種方式有些比較複雜,可是邏輯上卻又很清晰,保證惟一
相關文章
相關標籤/搜索