線程的使用
每個(gè)進(jìn)程都有一個(gè)地址空間和一個(gè)控制線程,但是我們經(jīng)常需要在同一個(gè)地址空間里運(yùn)行多個(gè)控制線程,它們協(xié)同工作完成任務(wù),線程被需要的理由如下:
- 包含多個(gè)線程的進(jìn)程配合工作的處理速度比單線程快
- 線程比進(jìn)程更輕量級(jí),創(chuàng)建和銷毀線程較之于進(jìn)程更為高效
- 在多核系統(tǒng)中,多線程更能充分利用資源
比如我們?nèi)粘J褂镁W(wǎng)易云音樂時(shí),如果該進(jìn)程只有一個(gè)線程,音樂播放本地歌曲的時(shí)候我們就不能同時(shí)在后臺(tái)下載歌曲,搜索歌曲的時(shí)候就要暫停播放音樂,這顯然是用戶無(wú)法接受的。如果我們采用多線程編程,可以用一個(gè)線程播放音樂,一個(gè)線程在后臺(tái)默默地下載音樂,一個(gè)線程接受用戶輸入并搜索結(jié)果,用戶體驗(yàn)自然非常好。

多線程編程在圖像處理和Web服務(wù)器開發(fā)方面是重頭戲。Web服務(wù)器可以在等待等待用戶請(qǐng)求時(shí)阻塞,每當(dāng)一個(gè)請(qǐng)求到達(dá)便彈出一個(gè)線程處理,可以同時(shí)處理大量請(qǐng)求,將應(yīng)答返回給用戶。
線程模型
進(jìn)程是一個(gè)正在執(zhí)行的程序的實(shí)例,用于把資源集中到一起,包括地址空間、打開的額文件,子進(jìn)程和信號(hào)等,進(jìn)程和進(jìn)程之間相對(duì)獨(dú)立,而線程共享進(jìn)程的資源,有著完全一樣的地址空間和全局變量,不同的是每個(gè)線程有著各自的堆棧。

線程的狀態(tài)
和進(jìn)程一樣,線程有3種狀態(tài):運(yùn)行(Running),就緒(Ready),阻塞(BLocked)
- Running運(yùn)行態(tài)(使用CPU中)
- Ready就緒態(tài)(可運(yùn)行,等待被調(diào)度)
-
Blocked阻塞態(tài)(等待外部事件發(fā)生)
線程狀態(tài)
一個(gè)處于運(yùn)行態(tài)的線程在等待用戶輸入時(shí)會(huì)發(fā)生轉(zhuǎn)換1進(jìn)入阻塞態(tài),在用戶輸入時(shí)會(huì)發(fā)生轉(zhuǎn)換2進(jìn)入就緒態(tài)。轉(zhuǎn)換3和轉(zhuǎn)換4可在操作系統(tǒng)的調(diào)度下發(fā)生。
在用戶空間實(shí)現(xiàn)線程
線程可在用戶空間和內(nèi)核空間實(shí)現(xiàn)。

在用戶空間實(shí)現(xiàn)線程,內(nèi)核并不會(huì)知道進(jìn)程內(nèi)有多個(gè)線程,仍把進(jìn)程當(dāng)做單線程進(jìn)程來(lái)對(duì)待,內(nèi)核通過其內(nèi)部的進(jìn)程表來(lái)管理進(jìn)程,而每個(gè)進(jìn)程內(nèi)部有一張用于供進(jìn)程管理線程的線程表。用戶空間實(shí)現(xiàn)線程的有點(diǎn)是顯而易見的:
- 由于不需要陷入內(nèi)核,線程的創(chuàng)建和銷毀完全在用戶空間,速度很快
- 每個(gè)進(jìn)程可以制定自己的調(diào)度算法
但是其有點(diǎn)完全掩蓋不了其缺點(diǎn):但其中一個(gè)線程阻塞時(shí),同一個(gè)進(jìn)程里面的所有線程都會(huì)被掛起。比如其中一個(gè)線程做I/O操作或是發(fā)生缺頁(yè)故障時(shí)(需要從磁盤載入頁(yè)面到物理內(nèi)存),該線程會(huì)被阻塞,原因是內(nèi)核管理的是進(jìn)程。
在內(nèi)核空間實(shí)現(xiàn)線程
現(xiàn)代主流的操作系統(tǒng)是在內(nèi)核空間實(shí)現(xiàn)線程,如下圖

和在用戶空間實(shí)現(xiàn)線程不同,此時(shí)線程表移到了內(nèi)核空間,由內(nèi)核對(duì)所有的線程單獨(dú)管理。當(dāng)一個(gè)線程阻塞時(shí),內(nèi)核可根據(jù)線程表調(diào)用同一進(jìn)程中的線程或是另外一個(gè)進(jìn)程中的線程,每個(gè)線程都是獨(dú)立的個(gè)體,一個(gè)線程阻塞就不會(huì)像在用戶空間中實(shí)現(xiàn)的線程那樣,阻塞整個(gè)進(jìn)程。
當(dāng)然,線程的創(chuàng)建和銷毀都需要執(zhí)行系統(tǒng)調(diào)用,從用戶空間陷入內(nèi)核空間,上下文切換的代價(jià)比較大。
