加入abc三個依次執行,可是a阻塞了,就直接不執行a了,直接跳過去執行b,和c,最後在執行apython
多道程序設計, 提升了cpu的利用率算法
進程:本質上就是一個一段程序的運行過程(抽象的概念)編程
線程:最小的執行單元(實例)多線程
進程:最小的資源單位(操做系統在分資源時,只能分到進程這裏)併發
進程就至關於一個容器,裏面能夠容納多個線程app
進程只是把資源集中到一塊兒,(進程只是一個資源單位,或者說一個資源集合),而線程纔是cpu上的執行單位異步
假若有兩個程序A和B,程序A在執行到一半的過程當中,須要讀取大量的數據輸入(I/O操做), 而此時CPU只能靜靜地等待任務A讀取完數據才能繼續執行,這樣就白白浪費了CPU資源。 是否是在程序A讀取數據的過程當中,讓程序B去執行,當程序A讀取完數據以後,讓 程序B暫停,而後讓程序A繼續執行? 固然沒問題,但這裏有一個關鍵詞:切換 既然是切換,那麼這就涉及到了狀態的保存,狀態的恢復,加上程序A與程序B所須要的系統資 源(內存,硬盤,鍵盤等等)是不同的。天然而然的就須要有一個東西去記錄程序A和程序B 分別須要什麼資源,怎樣去識別程序A和程序B等等,因此就有了一個叫進程的抽象
通俗的說就是
想象一位有一手好廚藝的計算機科學家egon正在爲他的女兒元昊烘製生日蛋糕。socket
他有作生日蛋糕的食譜,ide
廚房裏有所需的原料:麪粉、雞蛋、韭菜,蒜泥等。函數
在這個比喻中:
作蛋糕的食譜就是程序(即用適當形式描述的算法)
計算機科學家就是處理器(cpu)
而作蛋糕的各類原料就是輸入數據。
進程就是廚師閱讀食譜、取來各類原料以及烘製蛋糕等一系列動做的總和。
線程的出現是爲了下降上下文切換的消耗,提升系統的併發性,並突破一個進程只能幹同樣事的缺陷,
使到進程內併發成爲可能。
假設,一個文本程序,須要接受鍵盤輸入,將內容顯示在屏幕上,還須要保存信息到硬盤中。若只有
一個進程,勢必形成同一時間只能幹同樣事的尷尬(當保存時,就不能經過鍵盤輸入內容)。如有多
個進程,每一個進程負責一個任務,進程A負責接收鍵盤輸入的任務,進程B負責將內容顯示在屏幕上的
任務,進程C負責保存內容到硬盤中的任務。這裏進程A,B,C間的協做涉及到了進程通訊問題,並且
有共同都須要擁有的東西-------文本內容,不停的切換形成性能上的損失。如有一種機制,可使
任務A,B,C共享資源,這樣上下文切換所須要保存和恢復的內容就少了,同時又能夠減小通訊所帶
來的性能損耗,那就行了。是的,這種機制就是線程。
多線程指的是,在一個進程中開啓多個線程,簡單的講:若是多個任務共用一塊地址空間,那麼必須在一個進程內開啓多個線程。詳細的講分爲4點:
1. 多線程共享一個進程的地址空間
2. 線程比進程更輕量級,線程比進程更容易建立可撤銷,在許多操做系統中,建立一個線程比建立一個進程要快10-100倍,在有大量線程須要動態和快速修改時,這一特性頗有用
3. 若多個線程都是cpu密集型的,那麼並不能得到性能上的加強,可是若是存在大量的計算和大量的I/O處理,擁有多個線程容許這些活動彼此重疊運行,從而會加快程序執行的速度。
4. 在多cpu系統中,爲了最大限度的利用多核,能夠開啓多個線程,比開進程開銷要小的多。(這一條並不適用於python)
併發:在同一時間間隔內執行(指系統具備處理多個任務的能力,cpu切換)
並行:在同一時刻執行 (同時處理多個任務,)
關係:
並行是併發的一個子集
全部的併發處理都有排隊等候,喚醒和執行這三個步驟,因此併發是宏觀的觀念,在微觀上他們都是序列被處理的,只不過資源不會在某一個上被阻塞(通常是經過時間片輪轉),因此在宏觀上多個幾乎同時到達的請求同時在被處理。若是是同一時刻到達的請求也會根據優先級的不一樣,前後進入隊列排隊等候執行。
併發與並行是兩個既類似可是卻不相同的概念:
併發性:又稱共行性,是指處理多個同時性活動的能力,。
並行:指同時發生兩個併發事件,具備併發的含義。併發不必定並行,也能夠說併發事件之間不必定要同一時刻發生。
併發的實質是一個物理CPU(也能夠是多個物理CPU)在若干個程序之間多路複用,併發性是對有限物理資源強制行使 多用戶共享以提升效率。
並行指兩個或兩個以上事件或活動在同一時刻發生,在多道程序環境下,並行使多個程序同一時刻可在不一樣CPU上同時執行。
併發是在同一個cpu上同時(不是真正的同時,而是看來是同時,由於CPU要在多個程序之間切換)運行多個程序。
並行是每個CPU運行一個程序。
打個比方:併發就像一我的(CPU)喂兩個小孩(程序)吃飯,表面上是兩個小孩在吃飯,實際是一我的在喂。
並行就是兩我的喂兩個小孩子吃飯。
並行須要兩個或兩個以上的線程跑在不一樣的處理器上,併發能夠跑在一個處理器上經過時間片進行切換。
同步與異步
同步: 當一個進程執行到I/O(等待外部數據)的時候,你等待:------同步
異步: 不等待:一直等到數據接收成功,再回來處理----異步
同步 所謂同步,就是在發出一個功能調用時,在沒有獲得結果以前,該調用就不會返回。按照這個定義,其實絕大多數函數都是同步調用。可是通常而言,咱們在說同步、異步的時候,特指那些須要其餘部件協做或者須要必定時間完成的任務。 異步 #異步的概念和同步相對。當一個異步功能調用發出後,調用者不能馬上獲得結果。當該異步功能完成後,經過狀態、通知或回調來通知調用者。若是異步功能用狀態來通知,那麼調用者就須要每隔必定時間檢查一次,效率就很低(有些初學多線程編程的人,總喜歡用一個循環去檢查某個變量的值,這實際上是一 種很嚴重的錯誤)。若是是使用通知的方式,效率則很高,由於異步功能幾乎不須要作額外的操做。至於回調函數,其實和通知沒太多區 阻塞 阻塞調用是指調用結果返回以前,當前線程會被掛起(如遇到io操做)。函數只有在獲得結果以後纔會將阻塞的線程激活。有人也許會把阻塞調用和同步調用等同起來,實際上他是不一樣的。對於同步調用來講,不少時候當前線程仍是激活的,只是從邏輯上當前函數沒有返回而已。 #舉例: #1. 同步調用:apply一個累計1億次的任務,該調用會一直等待,直到任務返回結果爲止,但並未阻塞住(即使是被搶走cpu的執行權限,那也是處於就緒態); #2. 阻塞調用:當socket工做在阻塞模式的時候,若是沒有數據的狀況下調用recv函數,則當前線程就會被掛起,直到有數據爲止。 非阻塞 #非阻塞和阻塞的概念相對應,指在不能馬上獲得結果以前也會馬上返回,同時該函數不會阻塞當前線程。 總結 #1. 同步與異步針對的是函數/任務的調用方式:同步就是當一個進程發起一個函數(任務)調用的時候,一直等到函數(任務)完成,而進程繼續處於激活狀態。而異步狀況下是當一個進程發起一個函數(任務)調用的時候,不會等函數返回,而是繼續往下執行當,函數返回的時候經過狀態、通知、事件等方式通知進程任務完成。 #2. 阻塞與非阻塞針對的是進程或線程:阻塞是當請求不能知足的時候就將進程掛起,而非阻塞則不會阻塞當前進程