進程相關知識

 

  • 進程:顧名思義,進程即正在執行的一個過程。進程是對正在運行程序的一個抽象。html

  • 進程的概念起源於操做系統,是操做系統最核心的概念,也是操做系統提供的最古老也是最重要的抽象概念之一。操做系統的其餘全部內容都是圍繞進程的概念展開的。想要了解進程就必須先了解操做系統,老師文章node

    • PS:即便能夠利用的cpu只有一個(早期的計算機確實如此),也能保證支持(僞)併發的能力。將一個單獨的cpu變成多個虛擬的cpu(多道技術:時間多路複用和空間多路複用+硬件上支持隔離),沒有進程的抽象,現代計算機將不復存在。python

    • 操做系統的做用:linux

      • 一、隱藏醜陋複雜的硬件接口,提供良好的抽象接口
      • 二、管理、調度進程,而且將多個進程對硬件的競爭變得有序
    • 多道技術:所謂多道程序設計技術,就是指容許多個程序同時進入內存並運行。即同時把多個程序放入內存,並容許它們交替在CPU中運行,它們共享系統中的各類硬、軟件資源。當一道程序因I/O請求而暫停運行時,CPU便當即轉去運行另外一道程序。nginx

      • 產生背景:針對單核,實現併發(一個cup上運行多個程序)git

         
         
         
         
         
         
         
         
        如今的主機通常是多核,那麼每一個核都會利用多道技術
        有4個cpu,運行於cpu1的某個程序遇到io阻塞,會等待到io結束再從新調度,會被調度到4個
        cpu中的任意一個,具體由操做系統調度算法決定。
         
      • 空間上的複用:如內存中同時有多道程序web

      • 時間上的複用:複用一個cpu的時間片,算法

         
         
         
        xxxxxxxxxx
         
         
         
         
        強調:遇到io切,佔用cpu時間過長也切,核心在於切以前將進程的狀態保存下來,這樣
        才能保證下次切換回來時,能基於上次切走的位置繼續運行
         

    什麼是進程?

    • 進程(Process)是計算機中的程序關於某數據集合上的一次運行活動,是系統進行資源分配和調度的基本單位,是操做系統結構的基礎。在早期面向進程設計的計算機結構中,進程是程序的基本執行實體;在當代面向線程設計的計算機結構中,進程是線程的容器。程序是指令、數據及其組織形式的描述,進程是程序的實體。咱們本身在python文件中寫了一些代碼,這叫作程序,運行這個python文件的時候,這叫作進程。編程

      • 狹義定義:進程是正在運行的程序的實例
      • 廣義定義:進程是一個具備必定獨立功能的程序關於某個數據集合的一次運行活動。它是操做系統動態執行的基本單元,在傳統的操做系統中,進程既是基本的分配單元,也是基本的執行單元。
       
       
       
      x
       
       
       
       
      第一,進程是一個實體。每個進程都有它本身的地址空間,通常狀況下,包括文本區域(text region)(python的文件)、數據區域(data region)(python文件中定義的一些變量數據)和堆棧(stack region)。文本區域存儲處理器執行的代碼;數據區域存儲變量和進程執行期間使用的動態分配的內存;堆棧區域存儲着活動過程調用的指令和本地變量。
      第二,進程是一個「執行中的程序」。程序是一個沒有生命的實體,只有處理器賦予程序生命時(操做系統執行之),它才能成爲一個活動的實體,咱們稱其爲進程。[3] 
      進程是操做系統中最基本、重要的概念。是多道程序系統出現後,爲了刻畫系統內部出現的動態狀況,描述系統內部各道程序的活動規律引進的一個概念,全部多道程序設計操做系統都創建在進程的基礎上。
      動態性:進程的實質是程序在多道程序系統中的一次執行過程,進程是動態產生,動態消亡的。
      併發性:任何進程均可以同其餘進程一塊兒併發執行
      獨立性:進程是一個能獨立運行的基本單位,同時也是系統分配資源和調度的獨立單位;
      異步性:因爲進程間的相互制約,使進程具備執行的間斷性,即進程按各自獨立的、不可預知的速度向前推動
      結構特徵:進程由程序、數據和進程控制塊三部分組成。
      多個不一樣的進程能夠包含相同的程序:一個程序在不一樣的數據集裏就構成不一樣的進程,能獲得不一樣的結果;可是執行過程當中,程序不能發生改變。
       
    • 程序與進程的區別windows

       
       
       
      xxxxxxxxxx
       
       
       
       
      程序是指令和數據的有序集合,其自己沒有任何運行的含義,是一個靜態的概念。
      而進程是程序在處理機上的一次執行過程,它是一個動態的概念。
      程序能夠做爲一種軟件資料長期存在,而進程是有必定生命期的。
                          程序是永久的,進程是暫時的。
       

1、進程的調度

  • 要想多個進程交替運行,操做系統必須對這些進程進行調度,這個調度也不是隨即進行的,而是須要遵循必定的法則,由此就有了進程的調度算法。

    • 一、先來先服務調度算法

       
       
       
      xxxxxxxxxx
       
       
       
       
      先來先服務(FCFS)調度算法是一種最簡單的調度算法,該算法既可用於做業調度,也可用於進程調度。FCFS算法比較有利於長做業(進程),而不利於短做業(進程)。由此可知,本算法適合於CPU繁忙型做業,而不利於I/O繁忙型的做業(進程)。
       
    • 二、短做業優先調度算法

       
       
       
      xxxxxxxxxx
       
       
       
       
      短做業(進程)優先調度算法(SJ/PF)是指對短做業或短進程優先調度的算法,該算法既可用於做業調度,也可用於進程調度。但其對長做業不利;不能保證緊迫性做業(進程)被及時處理;做業的長短只是被估算出來的。
       
    • 三、時間片輪轉法

       
       
       
      xxxxxxxxxx
       
       
       
       
      時間片輪轉(Round Robin,RR)法的基本思路是讓每一個進程在就緒隊列中的等待時間與享受服務的時間成比例。在時間片輪轉法中,須要將CPU的處理時間分紅固定大小的時間片,例如,幾十毫秒至幾百毫秒。若是一個進程在被調度選中以後用完了系統規定的時間片,但又未完成要求的任務,則它自行釋放本身所佔有的CPU而排到就緒隊列的末尾,等待下一次調度。同時,進程調度程序又去調度當前就緒隊列中的第一個進程。
            顯然,輪轉法只能用來調度分配一些能夠搶佔的資源。這些能夠搶佔的資源能夠隨時被剝奪,並且能夠將它們再分配給別的進程。CPU是可搶佔資源的一種。但打印機等資源是不可搶佔的。因爲做業調度是對除了CPU以外的全部系統硬件資源的分配,其中包含有不可搶佔資源,因此做業調度不使用輪轉法。
      在輪轉法中,時間片長度的選取很是重要。首先,時間片長度的選擇會直接影響到系統的開銷和響應時間。若是時間片長度太短,則調度程序搶佔處理機的次數增多。這將使進程上下文切換次數也大大增長,從而加劇系統開銷。反過來,若是時間片長度選擇過長,例如,一個時間片能保證就緒隊列中所需執行時間最長的進程能執行完畢,則輪轉法變成了先來先服務法。時間片長度的選擇是根據系統對響應時間的要求和就緒隊列中所容許最大的進程數來肯定的。
            在輪轉法中,加入到就緒隊列的進程有3種狀況:
            一種是分給它的時間片用完,但進程還未完成,回到就緒隊列的末尾等待下次調度去繼續執行。
            另外一種狀況是分給該進程的時間片並未用完,只是由於請求I/O或因爲進程的互斥與同步關係而被阻塞。當阻塞解除以後再回到就緒隊列。
            第三種狀況就是新建立進程進入就緒隊列。
            若是對這些進程區別對待,給予不一樣的優先級和時間片從直觀上看,能夠進一步改善系統服務質量和效率。例如,咱們可把就緒隊列按照進程到達就緒隊列的類型和進程被阻塞時的阻塞緣由分紅不一樣的就緒隊列,每一個隊列按FCFS原則排列,各隊列之間的進程享有不一樣的優先級,但同一隊列內優先級相同。這樣,當一個進程在執行完它的時間片以後,或從睡眠中被喚醒以及被建立以後,將進入不一樣的就緒隊列。  
       
    • 四、多級反饋隊列

       
       
       
      xxxxxxxxxx
       
       
       
       
      前面介紹的各類用做進程調度的算法都有必定的侷限性。如短進程優先的調度算法,僅照顧了短進程而忽略了長進程,並且若是並未指明進程的長度,則短進程優先和基於進程長度的搶佔式調度算法都將沒法使用。
      而多級反饋隊列調度算法則沒必要事先知道各類進程所需的執行時間,並且還能夠知足各類類型進程的須要,於是它是目前被公認的一種較好的進程調度算法。在採用多級反饋隊列調度算法的系統中,調度算法的實施過程以下所述。
      (1) 應設置多個就緒隊列,併爲各個隊列賦予不一樣的優先級。第一個隊列的優先級最高,第二個隊列次之,其他各隊列的優先權逐個下降。該算法賦予各個隊列中進程執行時間片的大小也各不相同,在優先權愈高的隊列中,爲每一個進程所規定的執行時間片就愈小。例如,第二個隊列的時間片要比第一個隊列的時間片長一倍,……,第i+1個隊列的時間片要比第i個隊列的時間片長一倍。
      (2) 當一個新進程進入內存後,首先將它放入第一隊列的末尾,按FCFS原則排隊等待調度。當輪到該進程執行時,如它能在該時間片內完成,即可準備撤離系統;若是它在一個時間片結束時還沒有完成,調度程序便將該進程轉入第二隊列的末尾,再一樣地按FCFS原則等待調度執行;若是它在第二隊列中運行一個時間片後仍未完成,再依次將它放入第三隊列,……,如此下去,當一個長做業(進程)從第一隊列依次降到第n隊列後,在第n 隊列便採起按時間片輪轉的方式運行。
      (3) 僅當第一隊列空閒時,調度程序才調度第二隊列中的進程運行;僅當第1~(i-1)隊列均空時,纔會調度第i隊列中的進程運行。若是處理機正在第i隊列中爲某進程服務時,又有新進程進入優先權較高的隊列(第1~(i-1)中的任何一個隊列),則此時新進程將搶佔正在運行進程的處理機,即由調度程序把正在運行的進程放回到第i隊列的末尾,把處理機分配給新到的高優先權進程。
       
    • 進程之間的通訊總結

      管道(Pipe) 全部的 POSIX systems, Windows;
      
      命名管道(FIFO) 全部的 POSIX 系統, Windows;
      
      消息隊列(Message queue) 多數操做系統;
      
      信號量(Semaphore) 全部的 POSIX 系統, Windows;
      
      共享內存 全部的 POSIX 系統, Windows。
      
      

       

2、並行和併發

  • 經過進程之間的調度,也就是進程之間的切換,咱們用戶感知到的好像是兩個視頻文件同時在播放,或者音樂和遊戲同時在進行,那就讓咱們來看一下什麼叫作併發和並行。不管是並行仍是併發,在用戶看來都是'同時'運行的,無論是進程仍是線程,都只是一個任務而已,真是幹活的是cpu,cpu來作這些任務,而一個cpu同一時刻只能執行一個任務。

  • 併發:是僞並行,即看起來是同時運行。單個cpu+多道技術就能夠實現併發,(並行也屬於併發)

    你是一個cpu,你同時談了三個女友,每個均可以是一個戀愛任務,你被這三個任務共享要玩出併發戀愛的效果:
    應該是你先跟女朋友1去看電影,看了一會說:很差,我要拉肚子,而後跑去跟第二個女朋友吃飯,吃了一會說:那啥,我去趟洗手間,而後跑去跟女朋友3開了個房,而後在你的基友眼裏,你就在和三個女朋友同時在一塊兒玩。
    
  • 並行:同時運行,只有具有多個cpu才能實現並行

    將多個cpu合併成高速公路上的多個車道,進程就比如每一個車道上行駛的車輛,並行就是說,你們在本身的車道上行駛,會不影響,同時在開車。這就是並行
    
    單核下,能夠利用多道技術,多個核,每一個核也均可以利用多道技術(多道技術是針對單核而言的)。
    有四個核,六個任務,這樣同一時間有四個任務被執行,假設分別被分配給了cpu1,cpu2,cpu3,cpu4,
    一旦任務1遇到I/O就被迫中斷執行,此時任務5就拿到cpu1的時間片去執行,這就是單核下的多道技術
    而一旦任務1的I/O結束了,操做系統會從新調用它(需知進程的調度、分配給哪一個cpu運行,由操做系統說了算),可能被分配給四個cpu中的任意一個去執行
    
  • 多道技術概念回顧:

    • 內存中同時存入多道(多個)程序,cpu從一個進程快速切換到另一個,使每一個進程各自運行幾十或幾百毫秒,這樣,雖然在某一個瞬間,一個cpu只能執行一個任務,但在1秒內,cpu卻能夠運行多個進程,這就給人產生了並行的錯覺,即僞並行,以此來區分多處理器操做系統的真正硬件並行(多個cpu共享同一個物理內存)

    img

     

1.併發並行
    併發 是同一時間段內多個任務交替使用同一個cpu
    並行 是在同一個時刻多個任務在不一樣的cpu上同時執行
2.同步異步
    同步 發佈一個任務,要等待這個任務結束以後才能繼續
    異步 發佈一個任務,不等待這個任務的結束就能夠繼續執行當前的內容
3.阻塞非阻塞
    阻塞 : 在當前任務中cpu不工做
    非阻塞 : cpu還在繼續爲當前程序在執行
    
同步阻塞/同步非阻塞/異步阻塞/異步非阻塞

進程和程序
    進程就是運行中的程序
    每個進程在計算機中都有一個惟一的進程id,pid  process id
進程  是計算機中資源分配的最小單位
    三狀態 : 就緒 運行 阻塞
線程  是計算機中可以被CPU調度的最小單位
    是進程中的一個單位,它不能獨立存在

  • 併發:全部的併發處理都有排隊等候,喚醒,執行至少三個這樣的步驟.因此併發確定是宏觀概念,在微觀上他們都是序列被處理的,只不過資源不會在某一個上被阻塞(通常是經過時間片輪轉),因此在宏觀上看多個幾乎同時到達的請求同時在被處理。若是是同一時刻到達的請求也會根據優先級的不一樣,而前後進入隊列排隊等候執行。

  • 併發的實質是一個物理CPU(也能夠多個物理CPU) 在若干道程序之間多路複用,併發性是對有限物理資源強制行使多用戶共享以提升效率。 並行性指兩個或兩個以上事件或活動在同一時刻發生。在多道程序環境下,並行性使多個程序同一時刻可在不一樣CPU上同時執行。

    • 併發:是在同一個cpu上同時(不是真正的同時,而是看來是同時,由於cpu要在多個程序間切換)運行多個程序,多道技術

      img

    • 並行,是每一個cpu運行一個程序

      并发

3、進程狀態介紹

img

  • 在程序運行的過程當中,因爲被操做系統的調度算法控制,程序會進入幾個狀態:就緒,運行和阻塞。

    • 就緒(Ready)狀態:當進程已分配到除CPU之外的全部必要的資源,只要得到處理機即可當即執行,這時的進程狀態稱爲就緒狀態。

    • 執行/運行(Running)狀態當進程已得到處理機,其程序正在處理機上執行,此時的進程狀態稱爲執行狀態。

    • 阻塞(Blocked)狀態正在執行的進程,因爲等待某個事件發生而沒法執行時,便放棄處理機而處於阻塞狀態。引發進程阻塞的事件可有多種,例如,等待I/O完成、申請緩衝區不能知足、等待信件(信號)等。

      • 事件請求:input、sleep、文件輸入輸出、recv、accept等

        事件發生:sleep、input等完成了

      • 時間片到了以後有回到就緒狀態,這三個狀態不斷的在轉換

img

 

4、阻塞和非阻塞

  • 阻塞:就是幹不完不許回來,
    非阻塞:就是你先幹,我現看看有其餘事沒有,完了告訴我一聲
  • 咱們拿最經常使用的send和recv兩個函數來講吧... 好比你調用send函數發送必定的Byte,在系統內部send作的工做其實只是把數據傳輸(Copy)到TCP/IP協議棧的輸出緩衝區,它執行成功並不表明數據已經成功的發送出去了,若是TCP/IP協議棧沒有足夠的可用緩衝區來保存你Copy過來的數據的話...這時候就體現出阻塞和非阻塞的不一樣之處了:對於阻塞模式的socket send函數將不返回直到系統緩衝區有足夠的空間把你要發送的數據Copy過去之後才返回,而對於非阻塞的socket來講send會當即返回WSAEWOULDDBLOCK告訴調用者說:"發送操做被阻塞了!!!你想辦法處理吧..." 對於recv函數,一樣道理,該函數的內部工做機制實際上是在等待TCP/IP協議棧的接收緩衝區通知它說:嗨,你的數據來了.對於阻塞模式的socket來講若是TCP/IP協議棧的接收緩衝區沒有通知一個結果給它它就一直不返回:耗費着系統資源....對於非阻塞模式的socket該函數會立刻返回,而後告訴你:WSAEWOULDDBLOCK---"如今沒有數據,回頭在來看看"

5、同步和異步

  • 所謂同步,就是在發出一個功能調用時,在沒有獲得結果以前,該調用就不返回。按照這個定義,其實絕大多數函數都是同步調用(例如sin, isdigit等)。可是通常而言,咱們在說同步、異步的時候,特指那些須要其餘部件協做或者須要必定時間完成的任務。最多見的例子就是 SendMessage。該函數發送一個消息給某個窗口,在對方處理完消息以前,這個函數不返回。當對方處理完畢之後,該函數才把消息處理函數所返回的 LRESULT值返回給調用者。
  • 異步的概念和同步相對。當一個異步過程調用發出後,調用者不能馬上獲得結果。實際處理這個調用的部件在完成後,經過狀態、通知和回調來通知調用者。以 CAsycSocket類爲例(注意,CSocket從CAsyncSocket派生,可是起功能已經由異步轉化爲同步),當一個客戶端經過調用 Connect函數發出一個鏈接請求後,調用者線程馬上能夠向下運行。當鏈接真正創建起來之後,socket底 層會發送一個消息通知該對象。這裏提到執行部件和調用者經過三種途徑返回結果:狀態、通知和回調。可使用哪種依賴於執行部件的實現,除非執行部件提供多種選擇,不然不受調用者控制。若是執行部件用狀態來通知,那麼調用者就須要每隔必定時間檢查一次,效率就很低(有些初學多線程編程的人,總喜歡用一個循 環去檢查某個變量的值,這實際上是一種很嚴重的錯誤)。若是是使用通知的方式,效率則很高,由於執行部件幾乎不須要作額外的操做。至於回調函數,其實和通知 沒太多區別。

 

 

6、同步/異步 與 堵塞/非堵塞

  • 一、同步阻塞形式:效率最低。用例子來講,去排隊打飯,你專心排隊什麼別的事都不作。(cpu停滯)

  • 二、異步阻塞形式:異步操做是能夠被阻塞住的,只不過它不是在處理消息時阻塞,而是在等待消息通知時被阻塞。也就是說,能夠異步處理程序,一直往下走,遇到函數也往裏走,直到碰見io操做。就比如:你是個大boss很忙,你不可能在一個小業務上花時間,你把小人物安排給某個職員,當碰見須要你簽字的時候,他就回來找你"大佬這裏須要你籤個字……"

  • 同步非阻塞形式:其實是效率低下的,就好比說:你在排隊打飯,可是你很想快點打到飯(cpu未中止工做),跺腳。

  • 異步非阻塞形式:效率更高,就比如,你付了錢,店家給你小票,你能夠去座位上作本身的事,作好了叫你。

     

7、進程和線程

一個程序中至少有一個進程,而一個進程中至少有一個線程

  • 進程是運行中的程序,線程是進程內部的一個執行序列

  • 進程是資源分配的單元,線程是執行單元

  • 進程間切換代價大,線程間切換代價小

  • 進程擁有的資源多,線程擁有的資源少

  • 多個線程共享進程的資源

    工廠的資源 -> 系統分配的內存(獨立的一塊內存)
    
    工廠之間的相互獨立 -> 進程之間相互獨立
    
    多個工人協做完成任務 -> 多個線程在進程中協做完成任務
    
    工廠內有一個或多個工人 -> 一個進程由一個或多個線程組成
    
    工人之間共享空間 -> 同一進程下的各個線程之間共享程序的內存空間(包括代碼段、數據集、堆等)
    
  • 不管是線程仍是進程,使用的都是同步進制,當發生阻塞時,性能會大幅度下降,沒法充分利用CPU潛力,浪費硬件投資,更重要形成軟件模塊的鐵板化,緊耦合,沒法切割,不利於往後擴展和變化。

    無論是進程仍是線程,每次阻塞、切換都須要陷入系統調用(system call),先讓CPU跑操做系統的調度程序,而後再由調度程序決定該跑哪個進程(線程)。多個線程之間在一些訪問互斥的代碼時還須要加上鎖,現下流行的異步server都是基於事件驅動的(如nginx)。

      異步事件驅動模型中,把會致使阻塞的操做轉化爲一個異步操做,主線程負責發起這個異步操做,並處理這個異步操做的結果。因爲全部阻塞的操做都轉化爲異步操做,理論上主線程的大部分時間都是在處理實際的計算任務,少了多線程的調度時間,因此這種模型的性能一般會比較好。

     

8、進程的建立、結束與併發的實現

  • 有些操做系統功能比較單一,可是電腦的操做系統必須適用於多應用程序,須要有系統運行過程當中建立和撤銷的能力:

  • 建立新程序的方法:

    • 一、系統初始化(查看進程linux中用ps命令,windows中用任務管理器,前臺進程負責與用戶交互,後臺運行的進程與用戶無關,運行在後臺而且只在須要時才喚醒的進程,稱爲守護進程,如電子郵件、web頁面、新聞、打印)
    • 一個進程在運行過程當中開啓了子進程(如nginx開啓多進程,os.fork,subprocess.Popen等
    • 用戶的交互式請求,而建立一個新進程(如用戶雙擊暴風影音)
    • 一個批處理做業的初始化(只在大型機的批處理系統中應用)

    不管哪種,新進程的建立都是由一個已經存在的進程執行了一個用於建立進程的系統調用而建立的

    • 關於建立的子進程,UNIX和windows

      1.相同的是:進程建立後,父進程和子進程有各自不一樣的地址空間(多道技術要求物理層面實現進程之間內存的隔離),任何一個進程的在其地址空間中的修改都不會影響到另一個進程。

       2.不一樣的是:在UNIX中,子進程的初始地址空間是父進程的一個副本,提示:子進程和父進程是能夠有隻讀的共享內存區的。可是對於windows系統來講,從一開始父進程與子進程的地址空間就是不一樣的。

  • 進程的結束:

      1. 正常退出(自願,如用戶點擊交互式頁面的叉號,或程序執行完畢調用發起系統調用正常退出,在linux中用exit,在windows中用ExitProcess)
      2. 出錯退出(自願,python a.py中a.py不存在)
      3. 嚴重錯誤(非自願,執行非法指令,如引用不存在的內存,1/0等,能夠捕捉異常,try...except...)
      4. 被其餘進程殺死(非自願,如kill -9)
  • 進程併發的實現:進程併發的實如今於,硬件中斷一個正在運行的進程,把此時進程運行的全部狀態保存下來,爲此,操做系統維護一張表格,即進程表(process table),每一個進程佔用一個進程表項(這些表項也稱爲進程控制塊)、

    img

    該表存放了進程狀態的重要信息:程序計數器、堆棧指針、內存分配情況、全部打開文件的狀態、賬號和調度信息,以及其餘在進程由運行態轉爲就緒態或阻塞態時,必須保存的信息,從而保證該進程在再次啓動時,就像從未被中斷過同樣。(時間片輪轉)

相關文章
相關標籤/搜索