摘要:算法
1. 併發與並行的區別,何爲併發編程,併發編程的優點在哪編程
2. 多線程、多任務、多進程機制概述瀏覽器
3. 多線程、多任務、多進程機制與編程思想的關係服務器
首先介紹一下併發與並行,二者雖然只有一字之差,但實際上卻有着本質的區別,其概念以下:多線程
並行性(parallel):指在同一時刻,有多條指令在多個處理器上同時執行;架構
併發性(concurrency):指在同一時刻只能有一條指令執行,但多個進程指令被快速輪換執行,使得在宏觀上具備多個進程同時執行的效果。併發
咱們在解決編程問題時,一般使用順序編程來解決,即程序中的全部事物在任意時刻都只能執行一個步驟。然而對於某些問題,咱們但願可以並行地執行程序中的多個部分,來達到咱們想要的效果。在單處理器機器中,咱們能夠將程序劃分爲多個部分,而後每一個部分由該處理器併發執行。在多處理器機器中,咱們能夠將程序劃分多個部分,而後每一個部分分別在多個處理器上並行執行。固然爲了更加充分利用CPU資源,咱們也能夠在多個處理器上併發執行,那麼在這咱們就涉及到了另外一種編程模式了併發編程。併發編程又叫多線程編程。併發編程使咱們能夠將程序劃分爲多個分離的、獨立運行的任務。經過使用多線程機制,每一個獨立任務都將由線程來驅動。一個線程就是在進程中的一個單一的順序控制流,單個進程能夠擁有多個"併發執行"的任務。這樣使程序的每一個任務,都好像擁有一個本身的CPU同樣。但其底層機制仍是是切分CPU時間,CPU都有個時鐘頻率,表示每秒中能執行CPU指令的次數。在每一個時鐘週期內,CPU實際上只能去執行一條也有可能多條指令。操做系統將進程進行管理,輪流分配每一個進程很短的一段是時間但不必定是均分,而後在每一個進程內部,程序代碼本身處理該進程內部線程的時間分配,多個線程之間相互的切換去執行,這個切換時間也是很是短的因此一般咱們不須要考慮它。負載均衡
併發是指"發",不是處理,最多見的狀況就是許多人在一小段時間內都點擊了你的網站,發出了處理請求。併發編程是對併發情況的應對,在單處理器和多處理器機器上均可對其進行應對,可這個處理方案和架構以及算法有關。CPU通常是分時的,會在極短的時間內不停地切換給不一樣的線程使用,不管多少併發都會處理下去,只是時間問題,如何提升處理效率就看採用的技術了。性能
併發編程可使咱們的程序執行速度獲得提升,例如,若是你有一臺多處理器的機器,那麼就能夠在這些處理器之間分佈多個任務,從而能夠極大地提升吞吐量。這是Web服務器的常見狀況,通常Web服務器是一個多處理器機器,將爲每一個請求分配到一個線程中,那麼就能夠將大量的用戶請求分佈到多個CPU上進行併發處理。網站
可是,併發一般是提升運行在單處理器上的程序的性能。雖然,在單處理器上運行的併發程序開銷確實應該比該程序的全部部分都順序執行的開銷大,由於其中增長了所謂上"下文切換"的代價,即從一個任務切換到另外一個任務。表面上看,將程序的全部部分看成單個的任務運行好像是開銷更小一點,而且能夠節省上下文切換的代價。可是咱們的程序並不會按咱們設想的那樣一直正常運行,它會發生阻塞。若是程序中的某個任務由於某些緣由發生了阻塞,那麼該任務將不能繼續執行。若是沒有併發,則整個程序都將中止下來,直至外部條件發生變化。可是,若是使用併發來編寫程序,那麼當一個任務阻塞時,程序中的其餘任務還能夠繼續執行,所以這個程序能夠保持繼續向前執行,這樣就提升程序的執行效率和運行性能。
併發須要付出代價,包含複雜性代價,可是這些代價與在程序設計、資源負載均衡以及用戶方便使用方面的改進相比,就顯得微不足道了。一般,線程使你可以建立更加鬆散耦合的設計則,你的代碼中各個部分都必須顯式地關注那些一般能夠由線程來處理的任務。
幾乎全部的操做系統都支持同時運行多個任務,一個任務一般就是一個程序,每一個運行中的程序就是一個進程。當一個程序運行時,內部可能包含了多個順序執行流,每一個順序執行流就是一個線程。
實現併發最直接的方式是在操做系統級別使用進程,進程是運行在它本身的地址空間內的自包容的程序。多任務操做系統能夠經過週期性地將CPU從一個進程切換到另外一個進程,來實現同時運行多個進程。 儘管對於一個CPU而言,它在某個時間點只能運行一個進程,但CPU能夠在多個進程之間進行輪換執行,而且CPU的切換速度極高,使咱們沒法感知其切換的過程,就好像有多個進程在同時執行。
幾乎全部的操做系統都支持進程的概念,全部運行中的任務一般對應一個進程(Process)。當一個程序進入內存運行時,即變成一個進程。進程是處於運行過程當中的程序,而且具備必定的獨立功能,進程是系統進行資源分配和調度的一個獨立單位。通常而言,進程包含以下3個特徵。
■ 獨立性:進程是系統中獨立存在的實體,它能夠擁有本身獨立的資源,每個進程都擁有本身私有的地址空間。在沒有通過進程自己容許的狀況下,一個用戶進程不能夠直接訪問其餘進程的地址空間。
■ 動態性:進程與程序的區別在於,程序只是一個靜態的指令集合,而進程是一個正在系統中活動的指令集合。在進程中加入了時間的概念,進程具備本身的生命週期和各類不一樣的狀態,這些概念在程序中部是不具有的。
■ 併發性:多個進程能夠在單個處理器上併發執行,多個進程之間不會互相影響。
現代的操做系統都支持多進程的併發,但在具體的實現細節上可能由於硬件和操做系統的不一樣而採用不一樣的策略。比較經常使用的方式有:共用式的多任務操做策略,例如Windows 3.1和Mac OS 9。目前操做系統大多采用效率更高的搶佔式多任務操做策略,例如 VVindows NT、Windows 2000以及UNIX/Linux等操做系統。但對進程的併發一般會有數量和開銷的限制,以免它們在不一樣的併發系統之間的可應用性。爲了應對該問題,因此在多進程的基礎上提出了多線程的概念,下面將詳細介紹。
2.2.1 多線程概述
多線程則擴展了多進程的概念。使得同一個進程中也能夠同時併發處理多個任務。線程(Thread)也被稱做輕量級進程(Lightweight Process)。線程是進程的執行單元,就像進程在操做系統中的地位同樣,線程在程序中是獨立的、併發的執行流。當進程被初始化後,主線程就被建立了。對於絕大多數的應用程序來講,一般僅要求有一個主線程,但也能夠在該進程內建立多條順序執行流,這些順序執行流就是線程,每一個線程也是互相獨立的。
線程是進程的組成部分,一個進程能夠擁有多個線程,一個線程必須有一個父進程。線程能夠擁有本身的堆棧、本身的程序計數器和本身的局部變量,但不擁有系統資源,它與父進程的其餘線程共享該進程所擁有的所有資源。由於多個線程共享父進程裏的所有資源,所以編程更加方便;但必須更加當心,咱們必須確保線程不會妨礙同一進程裏的其餘線程。
2.2.2 多線程機制
線程模型爲編程帶來了便利,它簡化了在單一程序中同時交織在一塊兒的多個操做的處理。在使用線程時,CPU將輪流給每一個任務分配其佔用時間。每一個任務都以爲本身在一直佔用CPU,但事實上CPU時間是劃分紅片斷分配給了全部的任務。線程的一大好處是可使你從這個層次抽身出來,即代碼沒必要知道它是運行在具備一個仍是多個CPU的機器上。因此,使用線程機制是一種創建透明的、可擴展的程序的方法,若是程序行得太慢,爲機器增添一個CPU就能很容易地加快程序的運行速度。多任務和多線程每每是使用多處理器系統的最合理方式。
2.2.3 多線程調度
線程能夠完成必定的任務,能夠與其餘線程共享父進程中的共享變量及部分環境,相互之間協同來完成進程所要完成的任務。線程是獨立運行的,它並不知道進程中是否還有其餘線程存在,線程的執行是搶佔式的,也就是說,當前運行的線程在任什麼時候候均可能被掛起,以便另一個線程能夠運行。
一個線程能夠建立和撤銷另外一個線程,同一個進程中的多個線程之間能夠併發執行。從邏輯角度來看,多線程存在於一個應用程序中,讓一個應用程序中能夠有多個執行部分同時執行,但操做系統無須將多個線程看做多個獨立的應用,對多線程實現調度和管理以及資源分配。線程的調度和管理由進程自己負責完成。
2.2.4 多線程的優點
線程在程序中是獨立的、併發的執行流,與分隔的進程相比,進程中線程之間的隔離程度要小
01. 它們共享內存、文件句柄和其餘每一個進程應有的狀態。由於線程的劃分尺度小於進程,使得多線程程序的併發性高。進程在執行過程當中擁有獨立的內存單元,而多個線程共享內存,從而極大地提升了程序的運行效率
02. 線程比進程具備更高的性能,這是因爲同一個進程中的線程都有共性----多個線程共享同一個進程虛擬空間。線程共享的環境包括進程代碼段、進程的公有數據等。利用這些共享的數據,線程很容易實現相互之間的通訊
03. 當操做系統建立一個進程時,必須爲該進程分配獨立的內存空間,並分配大量的相關資源;但建立一個線程則簡單得多,所以使用多線程來實現併發比使用多進程實現併發的性能要高得多
總結起來,使用多線程編程具備以下幾個優勢:
01. 進程之間不能共享內存,但線程之間共享內存很是容易
02. 系統建立進程時須要爲該進程從新分配系統資源,但建立線程則代價小得多,所以使用多線程來實現多任務併發比多進程的效率高
03. Java語言內置了多線程功能支持,而不是單純地做爲底層操做系統的調度方式,從而簡化了Java的多線程編程
在實際應用中,多線程是很是有用的,一個瀏覽器必須能同時下載多個圖片;一個Web服務器必須能同時響應多個用戶請求;Java虛擬機自己就在後臺提供了一個超級線程來進行垃圾回收;圖形用戶界面(GUI)應用也須要啓動單獨的線程從主機環境收集用戶界面事件……總之,多線程在實際編程中的應用是很是普遍的。
若是,您認爲閱讀這篇博客讓您有些收穫,不妨點擊一下右下角的【推薦】。
若是,您但願更容易地發現個人新博客,不妨點擊一下左下角的【關注我】。
若是,您對個人博客所講述的內容有興趣,請繼續關注個人後續博客,我是【Sunddenly】。本文版權歸做者和博客園共有,歡迎轉載,但未經做者贊成必須保留此段聲明,且在文章頁面明顯位置給出原文鏈接,不然保留追究法律責任的權利