淺談linux線程模型和線程切換

本文從linux中的進程诵原、線程實現(xiàn)原理開始鞭莽,擴展到linux線程模型,最后簡單解釋線程切換的成本费尽。

剛開始學習仅父,不一定對叛薯,好心人們快來指正我啊啊啊s舷恕:牧铩!

linux中的進程與線程

首先明確進程與進程的基本概念:

  • 進程是資源分配的基本單位
  • 線程是CPU調(diào)度的基本單位
  • 一個進程下可能有多個線程
  • 線程共享進程的資源

基本原理

linux用戶態(tài)的進程省容、線程基本滿足上述概念抖拴,但內(nèi)核態(tài)不區(qū)分進程和線程⌒冉罚可以認為阿宅,內(nèi)核中統(tǒng)一執(zhí)行的是進程,但有些是“普通進程”(對應(yīng)進程process)笼蛛,有些是“輕量級進程”(對應(yīng)線程pthread或npthread)洒放,都使用task_struct結(jié)構(gòu)體保存保存。

使用fork創(chuàng)建進程伐弹,使用pthread_create創(chuàng)建線程拉馋。兩個系統(tǒng)調(diào)用最終都都調(diào)用了do_dork,而do_dork完成了task_struct結(jié)構(gòu)體的復制惨好,并將新的進程加入內(nèi)核調(diào)度煌茴。

進程是資源分配的基本單位、線程共享進程的資源

普通進程需要深拷貝虛擬內(nèi)存日川、文件描述符蔓腐、信號處理等;而輕量級進程之所以“輕量”龄句,是因為其只需要淺拷貝虛擬內(nèi)存等大部分信息回论,多個輕量級進程共享一個進程的資源。

線程是CPU調(diào)度的基本單位分歇、一個進程下可能有多個線程

linux加入了線程組的概念傀蓉,讓原有“進程”對應(yīng)線程,“線程組”對應(yīng)進程职抡,實現(xiàn)“一個進程下可能有多個線程”:

  • 操作系統(tǒng)中存在多個進程組
  • 一個進程組下有多個進程(1:n)
  • 一個進程對應(yīng)一個線程組(1:1)
  • 一個線程組下有多個線程(1:n)

task_struct中葬燎,使用pgid標的進程組,tgid標的線程組,pid標的進程或線程谱净。假設(shè)目前有一個進程組窑邦,則上述概念對應(yīng)如下:

  • 進程組中有一個主進程(父進程),pid等于進程組的pgid壕探;進程組下的其他進程都是父進程的子進程冈钦,pid不等于pgid
  • 每個進程對應(yīng)一個線程組,pid等于tgid李请。
  • 線程組中有一個“主線程”(勉強稱為“主線程”瞧筛,位的是與主進程對應(yīng);語義上絕不能稱為“父線程”)捻艳,pid等于該線程組的tgid驾窟;線程組下的其他線程都是與主線程平級,pid不等于tgid

因此认轨,調(diào)用getpgid返回pgid绅络,調(diào)用getpid應(yīng)返回tgid,調(diào)用gettid應(yīng)返回pid嘁字。使用的時候不要糊涂恩急。

進程下除主線程外的其他線程是CPU調(diào)度的基本單位,這很好理解纪蜒。而所謂主線程與所屬進程實際上是同一個task_struct衷恭,也能被CPU調(diào)度,因此主線程也是CPU調(diào)度的基本單位纯续。

tgid相同的所有線程組成了概念上的“進程”随珠,只有主線程在創(chuàng)建時會實際分配資源,其他線程通過淺拷貝共享主線程的資源猬错。結(jié)合前面介紹的普通線程與輕量級進程窗看,實現(xiàn)“進程是資源分配的基本單位”。

舉個栗子

pgid tgid pid
111 111 111
112 112 112
112 112 113
113 113 113
113 113 114
113 115 115
113 115 116
113 115 117
  • 存在3個進程組111倦炒、112显沈、113
    • 進程組111下有1個父進程111,單獨分配資源
      • 進程111下有1個線程111逢唤,共享進程111的資源
    • 進程組112下有1個父進程112拉讯,單獨分配資源
      • 進程112下有2個線程112、113鳖藕,共享進程112的資源
    • 進程組113下有1個父進程113魔慷,1個子進程115,各自單獨分配資源
      • 進程113下有2個線程113著恩、114院尔,共享進程113的資源
      • 進程115下有3個線程115纹烹、116、117召边,共享進程115的資源

小結(jié)

現(xiàn)在再來理解linux中的進程與線程就容易多了:

  • 進程是一個邏輯上的概念,用于管理資源裹驰,對應(yīng)task_struct中的資源
  • 每個進程至少有一個線程隧熙,用于具體的執(zhí)行,對應(yīng)task_struct中的任務(wù)調(diào)度信息
  • task_struct中的pid區(qū)分線程幻林,tgid區(qū)分進程贞盯,pgid區(qū)分進程組

linux線程模型

一對一

LinuxThreads與NPTL均采用一對一的線程模型,一個用戶線程對應(yīng)一個內(nèi)核線程沪饺。內(nèi)核負責每個線程的調(diào)度躏敢,可以調(diào)度到其他處理器上面。Linux 2.6默認使用NPTL線程庫整葡,一對一的線程模型件余。

優(yōu)點:

  • 實現(xiàn)簡單。

缺點:

  • 對用戶線程的大部分操作都會映射到內(nèi)核線程上遭居,引起用戶態(tài)和內(nèi)核態(tài)的頻繁切換啼器。
  • 內(nèi)核為每個線程都映射調(diào)度實體,如果系統(tǒng)出現(xiàn)大量線程俱萍,會對系統(tǒng)性能有影響端壳。

多對一

顧名思義,多對一線程模型中枪蘑,多個用戶線程對應(yīng)到同一個內(nèi)核線程上损谦,線程的創(chuàng)建、調(diào)度岳颇、同步的所有細節(jié)全部由進程的用戶空間線程庫來處理照捡。

優(yōu)點:

  • 用戶線程的很多操作對內(nèi)核來說都是透明的,不需要用戶態(tài)和內(nèi)核態(tài)的頻繁切換赦役。使線程的創(chuàng)建麻敌、調(diào)度、同步等非车嗨ぃ快术羔。

缺點:

  • 由于多個用戶線程對應(yīng)到同一個內(nèi)核線程,如果其中一個用戶線程阻塞乙漓,那么該其他用戶線程也無法執(zhí)行级历。
  • 內(nèi)核并不知道用戶態(tài)有哪些線程,無法像內(nèi)核線程一樣實現(xiàn)較完整的調(diào)度叭披、優(yōu)先級等

多對多

多對一線程模型是非常輕量的寥殖,問題在于多個用戶線程對應(yīng)到固定的一個內(nèi)核線程玩讳。多對多線程模型解決了這一問題:m個用戶線程對應(yīng)到n個內(nèi)核線程上,通常m>n嚼贡。由IBM主導的NGPT采用了多對多的線程模型熏纯,不過現(xiàn)在已廢棄。

優(yōu)點:

  • 兼具多對一模型的輕量
  • 由于對應(yīng)了多個內(nèi)核線程粤策,則一個用戶線程阻塞時樟澜,其他用戶線程仍然可以執(zhí)行
  • 由于對應(yīng)了多個內(nèi)核線程,則可以實現(xiàn)較完整的調(diào)度叮盘、優(yōu)先級等

缺點:

  • 實現(xiàn)復雜

線程切換

linux采用一對一的線程模型秩贰,用戶線程切換與內(nèi)核線程切換之間的差別非常小。同時柔吼,如果忽略用戶主動放棄用戶線程的執(zhí)行權(quán)(yield)帶來的開銷毒费,則只需要考慮內(nèi)核線程切換的開銷。

注意愈魏,這里僅僅是為了幫助理解做出的簡化觅玻。實際上,用戶線程庫在用戶線程的調(diào)度蝌戒、同步等過程中做了很多工作串塑,這部分開銷不能忽略

如JVM對Thread#yield()的解釋:如果底層OS不支持yield的語義北苟,則JVM讓用戶線程自旋至時間片結(jié)束桩匪,線程被動切換,以達到相似的效果友鼻。

什么引起線程切換

  • 時間片輪轉(zhuǎn)
  • 線程阻塞
  • 線程主動放棄時間片

線程切換的開銷

直接開銷

直接開銷是線程切換本身引起的傻昙,無可避免,必然發(fā)生彩扔。

用戶態(tài)與內(nèi)核態(tài)的切換

線程切換只能在內(nèi)核態(tài)完成妆档,如果當前用戶處于用戶態(tài),則必然引起用戶態(tài)與內(nèi)核態(tài)的切換虫碉。(<font color="red">“用戶態(tài)與內(nèi)核態(tài)的切換”具體帶來什么成本贾惦??敦捧?</font>)

上下文切換

前面說線程(或者叫做進程都隨意)信息需要用一個task_struct保存须板,線程切換時,必然需要將舊線程的task_struct從內(nèi)核切出兢卵,將新線程的切入习瑰,帶來上下文切換。除此之外秽荤,還需要切換寄存器甜奄、程序計數(shù)器柠横、線程棧(包括操作棧、數(shù)據(jù)棧)等课兄。

線程調(diào)度算法

線程調(diào)度算法需要管理線程的狀態(tài)牍氛、等待條件等,如果根據(jù)優(yōu)先級調(diào)度烟阐,則還需要維護優(yōu)先級隊列糜俗。如果線程切換比較頻繁,該成本不容小覷曲饱。

間接開銷

間接開銷是直接開銷的副作用,取決于系統(tǒng)實現(xiàn)和用戶代碼實現(xiàn)珠月。

緩存缺失

切換進程扩淀,需要執(zhí)行新邏輯。如果二者的訪問的地址空間不相近啤挎,則會引起緩存缺失驻谆,具體影響范圍取決于系統(tǒng)實現(xiàn)和用戶代碼實現(xiàn)。如果系統(tǒng)的緩存較大庆聘,則能減小緩存缺失的影響胜臊;如果用戶線程訪問數(shù)據(jù)的地址空間接近,則本身的緩存缺失率也比較低伙判。

對頁表等快慢表式結(jié)構(gòu)同理象对。


參考:


本文鏈接:淺談linux線程模型和線程切換
作者:猴子007
出處:https://monkeysayhi.github.io
本文基于 知識共享署名-相同方式共享 4.0 國際許可協(xié)議發(fā)布,歡迎轉(zhuǎn)載宴抚,演繹或用于商業(yè)目的勒魔,但是必須保留本文的署名及鏈接。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末菇曲,一起剝皮案震驚了整個濱河市冠绢,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌常潮,老刑警劉巖弟胀,帶你破解...
    沈念sama閱讀 212,294評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異喊式,居然都是意外死亡孵户,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,493評論 3 385
  • 文/潘曉璐 我一進店門垃帅,熙熙樓的掌柜王于貴愁眉苦臉地迎上來延届,“玉大人,你說我怎么就攤上這事贸诚》酵ィ” “怎么了厕吉?”我有些...
    開封第一講書人閱讀 157,790評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長械念。 經(jīng)常有香客問我头朱,道長,這世上最難降的妖魔是什么龄减? 我笑而不...
    開封第一講書人閱讀 56,595評論 1 284
  • 正文 為了忘掉前任项钮,我火速辦了婚禮,結(jié)果婚禮上希停,老公的妹妹穿的比我還像新娘烁巫。我一直安慰自己,他們只是感情好宠能,可當我...
    茶點故事閱讀 65,718評論 6 386
  • 文/花漫 我一把揭開白布亚隙。 她就那樣靜靜地躺著,像睡著了一般违崇。 火紅的嫁衣襯著肌膚如雪阿弃。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,906評論 1 290
  • 那天羞延,我揣著相機與錄音渣淳,去河邊找鬼。 笑死伴箩,一個胖子當著我的面吹牛入愧,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播嗤谚,決...
    沈念sama閱讀 39,053評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼砂客,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了呵恢?” 一聲冷哼從身側(cè)響起鞠值,我...
    開封第一講書人閱讀 37,797評論 0 268
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎渗钉,沒想到半個月后彤恶,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,250評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡鳄橘,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,570評論 2 327
  • 正文 我和宋清朗相戀三年声离,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片瘫怜。...
    茶點故事閱讀 38,711評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡术徊,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出鲸湃,到底是詐尸還是另有隱情赠涮,我是刑警寧澤子寓,帶...
    沈念sama閱讀 34,388評論 4 332
  • 正文 年R本政府宣布,位于F島的核電站笋除,受9級特大地震影響斜友,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜垃它,卻給世界環(huán)境...
    茶點故事閱讀 40,018評論 3 316
  • 文/蒙蒙 一鲜屏、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧国拇,春花似錦洛史、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,796評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至掉瞳,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間浪漠,已是汗流浹背陕习。 一陣腳步聲響...
    開封第一講書人閱讀 32,023評論 1 266
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留址愿,地道東北人该镣。 一個月前我還...
    沈念sama閱讀 46,461評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像响谓,于是被迫代替她去往敵國和親损合。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,595評論 2 350

推薦閱讀更多精彩內(nèi)容