1 、線程的3種實(shí)現(xiàn)方式
在傳統(tǒng)的操作系統(tǒng)中剂府,擁有資源和獨(dú)立調(diào)度的基本單位都是進(jìn)程拧揽。在引入線程的操作系統(tǒng)中,線程是獨(dú)立調(diào)度的基本單位腺占,進(jìn)程是資源擁有的基本單位淤袜。在同一進(jìn)程中,線程的切換不會引起進(jìn)程切換衰伯。在不同進(jìn)程中進(jìn)行線程切換,如從一個(gè)進(jìn)程內(nèi)的線程切換到另一個(gè)進(jìn)程中的線程時(shí)铡羡,會引起進(jìn)程切換
根據(jù)操作系統(tǒng)內(nèi)核是否對線程可感知,可以把線程分為內(nèi)核線程和用戶線程
在多線程操作系統(tǒng)中意鲸,各個(gè)系統(tǒng)的實(shí)現(xiàn)方式并不相同烦周,在有的系統(tǒng)中實(shí)現(xiàn)了用戶級線程,有的系統(tǒng)中實(shí)現(xiàn)了內(nèi)核級線程
有些情況下,也把內(nèi)核級線程叫做輕量級進(jìn)程(LWP), 但是這個(gè)是一個(gè)不準(zhǔn)備的描述, 其實(shí)LWP的術(shù)語是借自于SVR4/MP和Solaris 2.x系統(tǒng)中, 有些系統(tǒng)將LWP稱為虛擬處理器, 將之稱為輕量級進(jìn)程的原因可能是, 在內(nèi)核線程的支持下怎顾,LWP是獨(dú)立的調(diào)度單元读慎,就像普通的進(jìn)程一樣。所以LWP的最大特點(diǎn)還是每個(gè)LWP都有一個(gè)內(nèi)核線程支持槐雾。
2贪壳、 用戶級線程(多對一模型)
2.1 線程的用戶級線程實(shí)現(xiàn)方式
在用戶級線程中,
有關(guān)線程管理的所有工作都由應(yīng)用程序完成蚜退,內(nèi)核意識不到線程的存在. 應(yīng)用程序可以通過使用線程庫設(shè)計(jì)成多線程程序. 通常闰靴,應(yīng)用程序從單線程起始,在該線程中開始運(yùn)行钻注,在其運(yùn)行的任何時(shí)刻蚂且,可以通過調(diào)用線程庫中的派生例程創(chuàng)建一個(gè)在相同進(jìn)程中運(yùn)行的新線程。
用戶級線程僅存在于用戶空間中幅恋,此類線程的創(chuàng)建杏死、撤銷、線程之間的同步與通信功能捆交,都無須利用系統(tǒng)調(diào)用來實(shí)現(xiàn)淑翼。用戶進(jìn)程利用線程庫來控制用戶線程。由于線程在進(jìn)程內(nèi)切換的規(guī)則遠(yuǎn)比進(jìn)程調(diào)度和切換的規(guī)則簡單品追,不需要用戶態(tài)/核心態(tài)切換玄括,所以切換速度快。由于這里的處理器時(shí)間片分配是以進(jìn)程為基本單位肉瓦,所以每個(gè)線程執(zhí)行的時(shí)間相對減少為了在操作系統(tǒng)中加入線程支持遭京,采用了在用戶空間增加運(yùn)行庫來實(shí)現(xiàn)線程胃惜,這些運(yùn)行庫被稱為“線程包”,用戶線程是不能被操作系統(tǒng)所感知的哪雕。用戶線程多見于一些歷史悠久的操作系統(tǒng)船殉,例如Unix操作系統(tǒng)
用戶級線程駐留在用戶空間或模式。運(yùn)行時(shí)庫管理這些線程斯嚎,它也位于用戶空間利虫。它們對于操作系統(tǒng)是不可見的,因此無法被調(diào)度到處理器內(nèi)核堡僻。每個(gè)線程并不具有自身的線程上下文列吼。因此,就線程的同時(shí)執(zhí)行而言苦始,任意給定時(shí)刻每個(gè)進(jìn)程只能夠有一個(gè)線程在運(yùn)行寞钥,而且只有一個(gè)處理器內(nèi)核會被分配給該進(jìn)程。對于一個(gè)進(jìn)程陌选,可能有成千上萬個(gè)用戶級線程理郑,但是它們對系統(tǒng)資源沒有影響。運(yùn)行時(shí)庫調(diào)度并分派這些線程咨油。
下圖說明了用戶級線程的實(shí)現(xiàn)方式,
如同在圖中看到的那樣您炉,庫調(diào)度器從進(jìn)程的多個(gè)線程中選擇一個(gè)線程,然后該線程和該進(jìn)程允許的一個(gè)內(nèi)核線程關(guān)聯(lián)起來役电。內(nèi)核線程將被操作系統(tǒng)調(diào)度器指派到處理器內(nèi)核赚爵。用戶級線程是一種”多對一”的線程映射。
2.2 用戶級線程的特點(diǎn)
內(nèi)核對線程包一無所知法瑟。從內(nèi)核角度考慮冀膝,就是按正常的方式管理,即單線程進(jìn)程(存在運(yùn)行時(shí)系統(tǒng))
2.3 用戶級線程的優(yōu)點(diǎn)
用戶線程的優(yōu)點(diǎn)主要有
可以在不支持線程的操作系統(tǒng)中實(shí)現(xiàn)霎挟。
創(chuàng)建和銷毀線程窝剖、線程切換代價(jià)等線程管理的代價(jià)比內(nèi)核線程少得多, 因?yàn)楸4婢€程狀態(tài)的過程和調(diào)用程序都只是本地過程
允許每個(gè)進(jìn)程定制自己的調(diào)度算法教沾,線程管理比較靈活镀钓。這就是必須自己寫管理程序初烘,與內(nèi)核線程的區(qū)別
線程能夠利用的表空間和堆椝律空間比內(nèi)核級線程多
不需要陷阱,不需要上下文切換旺嬉,也不需要對內(nèi)存高速緩存進(jìn)行刷新馆揉,使得線程調(diào)用非臣饶拢快捷
線程的調(diào)度不需要內(nèi)核直接參與讶隐,控制簡單起胰。
2.4 用戶線程的缺點(diǎn)
用戶線程的缺點(diǎn)主要有
線程發(fā)生I/O或頁面故障引起的阻塞時(shí),如果調(diào)用阻塞系統(tǒng)調(diào)用則內(nèi)核由于不知道有多線程的存在整份,而會阻塞整個(gè)進(jìn)程從而阻塞所有線程, 因此同一進(jìn)程中只能同時(shí)有一個(gè)線程在運(yùn)行
頁面失效也會產(chǎn)生類似的問題待错。
一個(gè)單獨(dú)的進(jìn)程內(nèi)部,沒有時(shí)鐘中斷烈评,所以不可能用輪轉(zhuǎn)調(diào)度的方式調(diào)度線程
資源調(diào)度按照進(jìn)程進(jìn)行火俄,多個(gè)處理機(jī)下,同一個(gè)進(jìn)程中的線程只能在同一個(gè)處理機(jī)下分時(shí)復(fù)用
補(bǔ)充
在用戶級線程中讲冠,每個(gè)進(jìn)程里的線程表由運(yùn)行時(shí)系統(tǒng)管理瓜客。當(dāng)一個(gè)線程轉(zhuǎn)換到就緒狀態(tài)或阻塞狀態(tài)時(shí),在該線程表中存放重新啟動該線程所需的信息竿开,與內(nèi)核在進(jìn)程表中存放的進(jìn)程的信息完全一樣
3谱仪、內(nèi)核級線程
3.1 線程的內(nèi)核級線程實(shí)現(xiàn)
在內(nèi)核級線程中,內(nèi)核線程建立和銷毀都是由操作系統(tǒng)負(fù)責(zé)否彩、通過系統(tǒng)調(diào)用完成的疯攒。在內(nèi)核的支持下運(yùn)行,無論是用戶進(jìn)程的線程列荔,或者是系統(tǒng)進(jìn)程的線程敬尺,他們的創(chuàng)建、撤銷贴浙、切換都是依靠內(nèi)核實(shí)現(xiàn)的砂吞。
線程管理的所有工作由內(nèi)核完成,應(yīng)用程序沒有進(jìn)行線程管理的代碼崎溃,只有一個(gè)到內(nèi)核級線程的編程接口. 內(nèi)核為進(jìn)程及其內(nèi)部的每個(gè)線程維護(hù)上下文信息蜻直,調(diào)度也是在內(nèi)核基于線程架構(gòu)的基礎(chǔ)上完成。圖2-2(b)說明了內(nèi)核級線程的實(shí)現(xiàn)方式袁串。
內(nèi)核線程駐留在內(nèi)核空間概而,它們是內(nèi)核對象。有了內(nèi)核線程囱修,每個(gè)用戶線程被映射或綁定到一個(gè)內(nèi)核線程到腥。用戶線程在其生命期內(nèi)都會綁定到該內(nèi)核線程。一旦用戶線程終止蔚袍,兩個(gè)線程都將離開系統(tǒng)乡范。這被稱作”一對一”線程映射,
線程的創(chuàng)建啤咽、撤銷和切換等晋辆,都需要內(nèi)核直接實(shí)現(xiàn),即內(nèi)核了解每一個(gè)作為可調(diào)度實(shí)體的線程
這些線程可以在全系統(tǒng)內(nèi)進(jìn)行資源的競爭
內(nèi)核空間內(nèi)為每一個(gè)內(nèi)核支持線程設(shè)置了一個(gè)線程控制塊(TCB)宇整,內(nèi)核根據(jù)該控制塊瓶佳,感知線程的存在,并進(jìn)行控制
如圖所示,即內(nèi)核級線程的實(shí)現(xiàn)方式, 每個(gè)用戶線程都直接與一個(gè)內(nèi)核線程相關(guān)聯(lián).
操作系統(tǒng)調(diào)度器管理鳞青、調(diào)度并分派這些線程霸饲。運(yùn)行時(shí)庫為每個(gè)用戶級線程請求一個(gè)內(nèi)核級線程为朋。操作系統(tǒng)的內(nèi)存管理和調(diào)度子系統(tǒng)必須要考慮到數(shù)量巨大的用戶級線程。您必須了解每個(gè)進(jìn)程允許的線程的最大數(shù)目是多少厚脉。操作系統(tǒng)為每個(gè)線程創(chuàng)建上下文习寸。進(jìn)程的每個(gè)線程在資源可用時(shí)都可以被指派到處理器內(nèi)核。
3.2 內(nèi)核線程的特點(diǎn)
當(dāng)某個(gè)線程希望創(chuàng)建一個(gè)新線程或撤銷一個(gè)已有線程時(shí)傻工,它進(jìn)行一個(gè)系統(tǒng)調(diào)用
3.3 內(nèi)核線程的優(yōu)點(diǎn)
內(nèi)核線程的優(yōu)點(diǎn):
多處理器系統(tǒng)中霞溪,內(nèi)核能夠并行執(zhí)行同一進(jìn)程內(nèi)的多個(gè)線程
如果進(jìn)程中的一個(gè)線程被阻塞,能夠切換同一進(jìn)程內(nèi)的其他線程繼續(xù)執(zhí)行(用戶級線程的一個(gè)缺點(diǎn))
所有能夠阻塞線程的調(diào)用都以系統(tǒng)調(diào)用的形式實(shí)現(xiàn)中捆,代價(jià)可觀
當(dāng)一個(gè)線程阻塞時(shí)鸯匹,內(nèi)核根據(jù)選擇可以運(yùn)行另一個(gè)進(jìn)程的線程,而用戶空間實(shí)現(xiàn)的線程中泄伪,運(yùn)行時(shí)系統(tǒng)始終運(yùn)行自己進(jìn)程中的線程
信號是發(fā)給進(jìn)程而不是線程的殴蓬,當(dāng)一個(gè)信號到達(dá)時(shí),應(yīng)該由哪一個(gè)線程處理它蟋滴?線程可以“注冊”它們感興趣的信號
4 組合方式
在一些系統(tǒng)中科雳,使用組合方式的多線程實(shí)現(xiàn), 線程創(chuàng)建完全在用戶空間中完成,線程的調(diào)度和同步也在應(yīng)用程序中進(jìn)行. 一個(gè)應(yīng)用程序中的多個(gè)用戶級線程被映射到一些(小于或等于用戶級線程的數(shù)目)內(nèi)核級線程上脓杉。
下圖說明了用戶級與內(nèi)核級的組合實(shí)現(xiàn)方式, 在這種模型中糟秘,每個(gè)內(nèi)核級線程有一個(gè)可以輪流使用的用戶級線程集合
posix線程調(diào)度是一個(gè)混合模型,很靈活球散,足以在標(biāo)準(zhǔn)的特定實(shí)現(xiàn)中支持用戶級和內(nèi)核級的線程尿赚。模型中包括兩級調(diào)度–線程及和內(nèi)核實(shí)體級。線程級與用戶級線程類似蕉堰,內(nèi)核實(shí)體由內(nèi)核調(diào)度凌净。由線程庫來決定它需要多少內(nèi)核實(shí)體,以及他們是如何映射的屋讶。
POSIX 引入了一個(gè)線程調(diào)度競爭范圍(thread-scheduling contention scope)的概念冰寻,這個(gè). 概念賦予了程序員一些控制權(quán),使它們可以控制怎樣將內(nèi)核實(shí)體映射為線程皿渗。線程的contentionscope屬性可是PTHREAD_SCOPE_PROCESS,也可以是PTHREAD_SCOPE_SYSTEM斩芭。帶有PTHREAD_SCOPE_PROCESS屬性的線程與它所在的進(jìn)程中的其他線程競爭處理器資源。帶有PTHREAD_SCOPE_SYSTEM屬性的線程很像內(nèi)核級線程乐疆,他們在全系統(tǒng)的范圍內(nèi)競爭處理器資源划乖。POSIX的一種映射方式將PTHREAD_SCOPE_SYSTEM線程和內(nèi)核實(shí)體之間綁定起來。
內(nèi)核級線程創(chuàng)建時(shí)先設(shè)置線程屬性PTHREAD_SCOPE_SYSTEM挤土,代碼如下琴庵,:
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM); //設(shè)置內(nèi)核級的線程,以獲取較高的響應(yīng)速度
//創(chuàng)建線程
ret = pthread_create(&iAcceptThreadId, &attr, AcceptThread, NULL);
POSIX的標(biāo)準(zhǔn)中定義了兩個(gè)值:
PTHREAD_SCOPE_SYSTEM和PTHREAD_SCOPE_PROCESS,前者表示與系統(tǒng)中所有線程一起競爭CPU時(shí)間,后者表示僅與同進(jìn)程中的線程競爭CPU
默認(rèn)為PTHREAD_SCOPE_PROCESS迷殿。目前LinuxThreads僅實(shí)現(xiàn)了PTHREAD_SCOPE_SYSTEM一值儿礼。
關(guān)于線程的綁定,牽涉到另外一個(gè)概念:輕進(jìn)程(LWP:Light Weight Process)庆寺。輕進(jìn)程可以理解為內(nèi)核線程蚊夫,它位于用戶層和系統(tǒng)層之間。系統(tǒng)對線程資源的分配止邮、對線程的控制是通過輕進(jìn)程來實(shí)現(xiàn)的这橙,一個(gè)輕進(jìn)程可以控制一個(gè)或多個(gè)線程奏窑。默認(rèn)狀況下导披,啟動多少輕進(jìn)程、哪些輕進(jìn)程來控制哪些線程是由系統(tǒng)來控制的埃唯,這種狀況即稱為非綁定的撩匕。綁定狀況下,則顧名思義墨叛,即某個(gè)線程固定的”綁”在一個(gè)輕進(jìn)程之上止毕。被綁定的線程具有較高的響應(yīng)速度,這是因?yàn)镃PU時(shí)間片的調(diào)度是面向輕進(jìn)程的漠趁,綁定的線程可以保證在需要的時(shí)候它總有一個(gè)輕進(jìn)程可用扁凛。通過設(shè)置被綁定的輕進(jìn)程的優(yōu)先級和調(diào)度級可以使得綁定的線程滿足諸如實(shí)時(shí)反應(yīng)之類的要求。
設(shè)置線程綁定狀態(tài)的函數(shù)為pthread_attr_setscope闯传,它有兩個(gè)參數(shù)谨朝,第一個(gè)是指向?qū)傩越Y(jié)構(gòu)的指針,第二個(gè)是綁定類型甥绿,它有兩個(gè)取值:PTHREAD_SCOPE_SYSTEM(綁定的)和PTHREAD_SCOPE_PROCESS(非綁定的)字币。
5 、用戶級線程和內(nèi)核級線程的區(qū)別
內(nèi)核支持線程是OS內(nèi)核可感知的共缕,而用戶級線程是OS內(nèi)核不可感知的洗出。
用戶級線程的創(chuàng)建、撤消和調(diào)度不需要OS內(nèi)核的支持图谷,是在語言(如Java)這一級處理的翩活;而內(nèi)核支持線程的創(chuàng)建、撤消和調(diào)度都需OS內(nèi)核提供支持便贵,而且與進(jìn)程的創(chuàng)建隅茎、撤消和調(diào)度大體是相同的。
用戶級線程執(zhí)行系統(tǒng)調(diào)用指令時(shí)將導(dǎo)致其所屬進(jìn)程被中斷嫉沽,而內(nèi)核支持線程執(zhí)行系統(tǒng)調(diào)用指令時(shí)辟犀,只導(dǎo)致該線程被中斷。
在只有用戶級線程的系統(tǒng)內(nèi),CPU調(diào)度還是以進(jìn)程為單位堂竟,處于運(yùn)行狀態(tài)的進(jìn)程中的多個(gè)線程魂毁,由用戶程序控制線程的輪換運(yùn)行;在有內(nèi)核支持線程的系統(tǒng)內(nèi)出嘹,CPU調(diào)度則以線程為單位席楚,由OS的線程調(diào)度程序負(fù)責(zé)線程的調(diào)度。
用戶級線程的程序?qū)嶓w是運(yùn)行在用戶態(tài)下的程序税稼,而內(nèi)核支持線程的程序?qū)嶓w則是可以運(yùn)行在任何狀態(tài)下的程序烦秩。