新聞中心
一、了解進(jìn)程、線程模型

成都創(chuàng)新互聯(lián)公司-專業(yè)網(wǎng)站定制、快速模板網(wǎng)站建設(shè)、高性價比西鄉(xiāng)網(wǎng)站開發(fā)、企業(yè)建站全套包干低至880元,成熟完善的模板庫,直接使用。一站式西鄉(xiāng)網(wǎng)站制作公司更省心,省錢,快速模板網(wǎng)站建設(shè)找我們,業(yè)務(wù)覆蓋西鄉(xiāng)地區(qū)。費用合理售后完善,十多年實體公司更值得信賴。
每次學(xué)習(xí)一個新技術(shù),我會先去了解這個技術(shù)的背景,這個過程看似浪費時間,其實在后續(xù)的學(xué)習(xí)過程中,能夠促進(jìn)理解很多問題。所以對于線程這個概念,我會先從操作系統(tǒng)講起。因為操作系統(tǒng)的發(fā)展帶來了軟件層面的變革。
從多線程的發(fā)展來看,可以操作系統(tǒng)的發(fā)展分為三個歷史階段:
- 真空管和穿孔卡片
- 晶體管和批處理系統(tǒng)
- 集成電路和多道程序設(shè)計
最早的計算機只能解決簡單的數(shù)學(xué)運算問題,比如正弦、余弦等。運行方式:程序員首先把程序?qū)懙郊埳?,然后穿孔成卡票,再把卡片盒帶入到專門的輸入室。輸入室會有專門的操作員將卡片的程序輸入到計算機上。計算機運行完當(dāng)前的任務(wù)以后,把計算結(jié)果從打印機上進(jìn)行輸出,操作員再把打印出來的結(jié)果送入到輸出室,程序員就可以從輸出室取到結(jié)果。然后,操作員再繼續(xù)從已經(jīng)送入到輸入室的卡片盒中讀入另一個任務(wù)重復(fù)上述的步驟。
操作員在機房里面來回調(diào)度資源,造成計算機存在大量的空閑狀態(tài) 。而當(dāng)時的計算機是非常昂貴的,人們?yōu)榱藴p少這種資源的浪費。就采用了 批處理系統(tǒng)來解決
批處理操作系統(tǒng)的運行方式:在輸入室收集全部的作業(yè),然后用一臺比較便宜的計算機把它們讀取到磁帶上。然后把磁帶輸入到計算機,計算機通過讀取磁帶的指令來進(jìn)行運算,最后把結(jié)果輸出磁帶上。批處理操作系統(tǒng)的好處在于,計算機會一直處于運算狀態(tài),合理的利用了計算機資源。(運行流程如下圖所示)
(注:此圖來源于現(xiàn)代操作系統(tǒng))
批處理操作系統(tǒng)雖然能夠解決計算機的空閑問題,但是當(dāng)某一個作業(yè)因為等待磁盤或者其他I/O操作而暫停,那CPU就只能阻塞直到該I/O完成,對于CPU操作密集型的程序,I/O操作相對較少,因此浪費的時間也很少。但是對于I/O操作較多的場景來說,CPU的資源是屬于嚴(yán)重浪費的。
多道程序設(shè)計的出現(xiàn)解決了這個問題,就是把內(nèi)存分為幾個部分,每一個部分放不同的程序。當(dāng)一個程序需要等待I/O操作完成時。那么CPU可以切換執(zhí)行內(nèi)存中的另外一個程序。如果內(nèi)存中可以同時存放足夠多的程序,那CPU的利用率可以接近100%。
在這個時候,引入了第一個概念- 進(jìn)程, 進(jìn)程的本質(zhì)是一個正在執(zhí)行的程序,程序運行時系統(tǒng)會創(chuàng)建一個進(jìn)程,并且給每個進(jìn)程分配獨立的內(nèi)存地址空間保證每個進(jìn)程地址不會相互干擾。同時,在CPU對進(jìn)程做時間片的切換時,保證進(jìn)程切換過程中仍然要從進(jìn)程切換之前運行的位置出開始執(zhí)行。所以進(jìn)程通常還會包括程序計數(shù)器、堆棧指針。
有了進(jìn)程以后,可以讓操作系統(tǒng)從宏觀層面實現(xiàn)多應(yīng)用并發(fā)。而并發(fā)的實現(xiàn)是通過CPU時間片不端切換執(zhí)行的。對于單核CPU來說,在任意一個時刻只會有一個進(jìn)程在被CPU調(diào)度
有了進(jìn)程以后,為什么還會出現(xiàn)線程呢?
在一個應(yīng)用進(jìn)程中,會存在多個同時執(zhí)行的任務(wù),如果其中一個任務(wù)被阻塞,將會引起不依賴該任務(wù)的任務(wù)也被阻塞。舉個具體的例子來說,我們平常用word文檔編輯內(nèi)容的時候,都會有一個自動保存的功能,這個功能的作用是,當(dāng)計算機出現(xiàn)故障的情況下如果用戶未保存文檔,則能夠恢復(fù)到上一次自動保存的點。假設(shè)word的自動保存因為磁盤問題導(dǎo)致寫入較慢,勢必會影響到用戶的文檔編輯功能,直到磁盤寫入完成用戶才可編輯,這種體驗是很差的。如果我們把一個進(jìn)程中的多個任務(wù)通過線程的方式進(jìn)行隔離,那么按照前面提到的進(jìn)程演進(jìn)的理論來說,在單核心CPU架構(gòu)中可以通過CPU的時間片切換實現(xiàn)線程的調(diào)度充分利用CPU資源以達(dá)到最大的性能。
我們用了比較長的篇幅介紹了進(jìn)程、線程發(fā)展的歷史??偟膩碚f是人們對于計算機的要求越來越高;對于計算機本身的資源的利用率也在不斷提高。
二、線程的優(yōu)勢
前面分析了線程的發(fā)展歷史,這里簡單總結(jié)一下線程有的優(yōu)勢如下:
- 線程可以認(rèn)為是輕量級的進(jìn)程,所以線程的創(chuàng)建、銷毀要比進(jìn)程更快
- 從性能上考慮,如果進(jìn)程中存在大量的I/O處理,通過多線程能夠加快應(yīng)用程序的執(zhí)行速度(通過CPU時間片的快速切換)。
- 由于線程是CPU的最小調(diào)度單元,所以在多CPU架構(gòu)中能夠?qū)崿F(xiàn)真正的并行執(zhí)行。每一個CPU可以調(diào)度一個線程
這里有兩個概念很多人沒有搞明白,就是并行和并發(fā):
并行:同時執(zhí)行多個任務(wù),在多核心CPU架構(gòu)中,一個CPU核心運行一個線程,那么4核心CPU,可以同時執(zhí)行4個線程
并發(fā):同處理多個任務(wù)的能力,通常我們會通過TPS或者QPS來表示某某系統(tǒng)支持的并發(fā)數(shù)是多少。
總的來說,并行是并發(fā)的子集。也就是說我們可以寫一個擁有多線程并行的程序,如果在沒有多核心CPU來執(zhí)行這些線程,那就不能以并行的方式來運行程序中的多個線程。所以并發(fā)程序可以是并行的,也可以不是。Erlang之父Joe Armstrong通過一張圖型的方式來解釋并發(fā)和并行的區(qū)別,圖片如下
三、線程的生命周期
線程是存在生命周期的,從線程的創(chuàng)建到銷毀,可能會經(jīng)歷6種不同的狀態(tài),但是在一個時刻線程只能處于其中一種狀態(tài)。
- NEW:初始狀態(tài),線程被創(chuàng)建時候的狀態(tài),還沒有調(diào)用start方法
- RUNNABLE:運行狀態(tài),運行狀態(tài)包含就緒和運行兩種狀態(tài),因為線程啟動以后,并不是立即執(zhí)行,而是需要通過調(diào)度去分配CPU時間片
- BLOCKED:阻塞狀態(tài),當(dāng)線程去訪問一個加鎖的方法時,如果已經(jīng)有其他線程獲得鎖,那么當(dāng)前線程會處于阻塞狀態(tài)
- WAITING:等待狀態(tài),設(shè)置線程進(jìn)入等待狀態(tài)等待其他線程做一些特定的動作進(jìn)行觸發(fā)
- TIME_WAITING:超時等待狀態(tài),和WAITING狀態(tài)的區(qū)別在于超時以后自動返回
- TERMINATED:終止?fàn)顟B(tài),線程執(zhí)行完畢
下圖整理了線程的狀態(tài)變更過程及變更的操作,每一個具體的操作原理,我會在后續(xù)的文章中進(jìn)行詳細(xì)分析。
這里有一個問題大家可能搞不明白,BLOCKED和WAITING這兩個阻塞有什么區(qū)別?
- BLOCKED狀態(tài)是指當(dāng)前線程在等待一個獲取鎖的操作時的狀態(tài)。
- WAITING是通過Object.wait或者Thread.join、LockSupport.park等操作實現(xiàn)的
- BLOCKED是被動的標(biāo)記,而WAITING是主動操作
- 如果說得再深入一點,處于WAITING狀態(tài)的線程,被喚醒以后,需要進(jìn)入同步隊列去競爭鎖操作,而在同步隊列中,如果已經(jīng)有其他線程持有鎖,則線程會處于BLOCKED狀態(tài)。所以可以說BLOCKED狀態(tài)是處于WAITING狀態(tài)的線程重新喚醒的必經(jīng)的狀態(tài)
四、線程的應(yīng)用場景
線程的出現(xiàn),在多核心CPU架構(gòu)下實現(xiàn)了真正意義上的并行執(zhí)行。也就是說,一個進(jìn)程內(nèi)多個任務(wù)可以通過多線程并行執(zhí)行來提高程序運行的性能。那線程的使用場景有哪些呢?
- 執(zhí)行后臺任務(wù),在很多場景中,可能會有一些定時的批量任務(wù),比如定時發(fā)送短信、定時生成批量文件。在這些場景中可以通過多線程的來執(zhí)行
- 異步處理,比如在用戶注冊成功以后給用戶發(fā)送優(yōu)惠券或者短信,可以通過異步的方式來執(zhí)行,一方面提升主程序的執(zhí)行性能;另一方面可以解耦核心功能,防止非核心功能對核心功能造成影響
- 分布式處理,比如fork/join,將一個任務(wù)拆分成多個子任務(wù)分別執(zhí)行
- BIO模型中的線程任務(wù)分發(fā),也是一種比較常見的使用場景,一個請求對應(yīng)一個線程
合理的利用多線程,可以提升程序的吞吐量。同時,還可以通過增加CPU的核心數(shù)來提升程序的性能,這就體現(xiàn)了伸縮性的特點。
當(dāng)前文章:了解線程的前世今生
轉(zhuǎn)載來源:http://m.fisionsoft.com.cn/article/coogpij.html


咨詢
建站咨詢
