那些程:進(jìn)程郑原、線程击敌、協(xié)程

導(dǎo)讀

要理解進(jìn)程與線程是偷,首先得了解并發(fā)與并行感挥。

并發(fā)與并行

  • 并發(fā)
    單核CPU時(shí)間分片,多個(gè)程序切換執(zhí)行冻辩,這就是并發(fā)猖腕。并發(fā)是共享內(nèi)存的,所以需要加鎖恨闪。
    因?yàn)椴l(fā)共享內(nèi)存倘感,并且會(huì)幾個(gè)程序互相切換執(zhí)行,所以在一個(gè)CPU執(zhí)行的并發(fā)必須處理上下文切換的問(wèn)題咙咽。 進(jìn)程就是在這種背景下老玛,被提出的。進(jìn)程就是一些相關(guān)線程的統(tǒng)稱钧敞,是一些相關(guān)線程的集合蜡豹。進(jìn)程搭配虛擬內(nèi)存、進(jìn)行表等溉苛,可以管理獨(dú)立程序的運(yùn)行余素、切換。
    并發(fā)也就是多線程炊昆。

由上面這段話可見,程序在運(yùn)行過(guò)程中威根,對(duì)計(jì)算機(jī)資源的分配是個(gè)很重大的問(wèn)題凤巨,于是出現(xiàn)了操作系統(tǒng)專門干這個(gè)活。操作系統(tǒng)核心的操作是陷入內(nèi)核(Kernel)洛搀,切換到操作系統(tǒng)敢茁,讓內(nèi)核來(lái)做。

  • 并行
    多核CPU幾個(gè)程序同時(shí)執(zhí)行留美,這就是并行彰檬。并行也就是我們所說(shuō)的多進(jìn)程。

進(jìn)程和線程

  • 進(jìn)程
    進(jìn)程是一個(gè)容器谎砾,也就是一個(gè)程序逢倍。
    進(jìn)程的切換:
  1. 切換頁(yè)全局目錄(Page Global Directory)來(lái)加載新的地址空間,實(shí)際上會(huì)加載新進(jìn)程的cr3寄存器值景图。
  2. 切換內(nèi)核堆棧和硬件上下文较雕,這些包含了內(nèi)核執(zhí)行一個(gè)新進(jìn)程的所有信息,包含了CPU寄存器。
  • 線程
    線程是容器里的工作單元亮蒋。上面說(shuō)并發(fā)的時(shí)候講到扣典,并發(fā)是共享內(nèi)存的,也就說(shuō)這些并發(fā)的線程會(huì)共享一個(gè)地址空間慎玖。線程的切換贮尖,不需要重新加載地址空間,頁(yè)面緩沖區(qū)趁怔,需要切換寄存器上下文和棧湿硝。開銷相對(duì)較小。

    線程在切換任務(wù)的時(shí)候痕钢,切換寄存器上下文和棧是搶占式的(Preeemptive multitasking)图柏,誰(shuí)搶了是誰(shuí)的,這就導(dǎo)致了線程之間的執(zhí)行順序是無(wú)法保證的任连,所以使用線程時(shí)需要小心操作同步問(wèn)題蚤吹。

    進(jìn)程和線程的相同點(diǎn)

    線程和進(jìn)程的切換,都需要陷入系統(tǒng)調(diào)用随抠,即CPU先跑操作系統(tǒng)的調(diào)度程序裁着,然后再由調(diào)度程序決定該炮哪一個(gè)進(jìn)程(線程)

同步和異步

首先要明確一點(diǎn),同步/異步這個(gè)討論對(duì)于IO密集型才有意義拱她。
因?yàn)閷?duì)于計(jì)算密集型程序來(lái)說(shuō)二驰,
你等或者不等,
計(jì)算任務(wù)都在那里秉沼,
不多不少桶雀。
對(duì)于IO密集型程序來(lái)說(shuō),
你等就是占著茅坑不拉屎唬复。你的肚子還沒有應(yīng)答矗积,你蹲在那有什么用?反而不如騰出地方來(lái)敞咧,讓程序別的地方先用著棘捣。等你確實(shí)要拉了,再來(lái)休建。這個(gè)坑位乍恐,就是CPU啊测砂!

協(xié)程

協(xié)程茵烈,coroutine,也叫纖程(Fiber),或綠色線程砌些。
協(xié)程是用戶態(tài)的輕量級(jí)線程瞧毙。這句話是什么鬼?

協(xié)程擁有自己的寄存器上下文和棧。協(xié)程調(diào)度切換時(shí)宙彪,將寄存器上下文和棧保存到其他地方矩动,切回來(lái)的時(shí)候,揮發(fā)原來(lái)保存的寄存器上下文和棧释漆。

由此可見悲没,協(xié)程能保留上一次調(diào)用時(shí)的狀態(tài)。協(xié)程的任務(wù)切換是由用戶自己控制的男图,不存在搶占示姿,所以這種叫做協(xié)作式多任務(wù)

協(xié)程也是單線程的逊笆,本質(zhì)也是異步+回調(diào)栈戳,但是它是經(jīng)過(guò)包裝的,寫出的代碼看著是同步的代碼难裆。寫過(guò)Node的應(yīng)該深有體會(huì)子檀。

Go研究出來(lái)了一套協(xié)程的調(diào)度算法,所以Go的協(xié)程叫做Goroutine乃戈。
Kotlin也有褂痰,C#也有,不是什么新鮮玩意症虑。但是在語(yǔ)言的層面上的支持缩歪,還是第一個(gè)。

事件驅(qū)動(dòng)

事件驅(qū)動(dòng)是事先編寫一個(gè)事件循環(huán)谍憔,這個(gè)事件循環(huán)程序不斷地檢查目前要處理的信息匪蝙,多用在GUI框架、頁(yè)面上的JS事件习贫。如果這個(gè)事件收到了要處理的事件的信號(hào)逛球,就異步去執(zhí)行。

然后這個(gè)信號(hào)是推拉結(jié)合的沈条。

基于事件驅(qū)動(dòng)的編程是單線程思維,特點(diǎn)是異步+回調(diào)诅炉。

協(xié)程的優(yōu)劣

協(xié)程的優(yōu)點(diǎn)

  • 跨平臺(tái)/跨體系架構(gòu)
  • 與進(jìn)程/線程相比蜡歹,上下文切換的開銷
  • 與線程相比,不需要原子操作鎖定及同步
  • 與事件驅(qū)動(dòng)相比涕烧,方便切換控制流月而,編程模型簡(jiǎn)單
  • 高并發(fā),一個(gè)CPU支持上萬(wàn)的協(xié)程

協(xié)程的缺點(diǎn)

  • 無(wú)法利用多核資源议纯,事件驅(qū)動(dòng)父款,本質(zhì)是個(gè)單線程的循環(huán)而已。需要配合進(jìn)程來(lái)執(zhí)行。

演進(jìn)軌跡

IO密集型程序:多進(jìn)程 -> 多線程 -> 事件驅(qū)動(dòng) -> 協(xié)程
CPU密集型程序:多進(jìn)程 -> 多線程

  1. 為什么從多進(jìn)程到多線程是一種進(jìn)步憨攒?
    因?yàn)榫€程比進(jìn)行性能開銷小世杀,而且多線程之間數(shù)據(jù)通信與同步更加方便。想同步的時(shí)候就訪問(wèn)肝集,修改的時(shí)候加把鎖就可以了瞻坝。

    這個(gè)也是符合我們直覺的。比如要需要一個(gè)程序某個(gè)部分的幾個(gè)不同運(yùn)算值杏瞻,是在后臺(tái)多起幾個(gè)進(jìn)程分別跑呢所刀?還是寫成多線程處理呢?實(shí)踐中捞挥,我們很少見到開多進(jìn)程的吧浮创?

  2. 那為什么CPU密集型任務(wù)沒有發(fā)展到事件驅(qū)動(dòng)、協(xié)程呢砌函?
    因?yàn)镃PU密集型的任務(wù)斩披,一般都是需要計(jì)算的,計(jì)算是需要CPU的胸嘴。CPU的多少是和系統(tǒng)的硬件相關(guān)雏掠,異步是改變不了這一點(diǎn)的,等待的時(shí)候不能計(jì)算劣像,等待完了該算的還得接著算乡话,所以說(shuō)沒什么卵用。

多進(jìn)程(并行)/多線程(并發(fā))/協(xié)程各自的適用場(chǎng)景

為什么程序多了電腦卡

進(jìn)程多了耳奕,操作系統(tǒng)會(huì)頻繁切換進(jìn)程绑青。從上面可知,進(jìn)程一切換屋群,頁(yè)全局目錄闸婴、內(nèi)核堆棧、硬件上下文都會(huì)變芍躏。一旦進(jìn)程變多之后邪乍,頻繁切換會(huì)擠占大部分資源。

相關(guān)知識(shí)補(bǔ)充

image.png

啥是“陷入內(nèi)核”对竣?看到這個(gè)詞的第一反應(yīng)是寫錯(cuò)了庇楞。其實(shí)不然。
要說(shuō)請(qǐng)首先需明確否纬,特權(quán)級(jí)的概念吕晌。就行l(wèi)inux系統(tǒng)里面,喜歡劃分管理員和用戶等不同權(quán)限角色一樣临燃。在系統(tǒng)中睛驳,為了讓資源調(diào)配集中管理烙心,便有了特權(quán)級(jí)這個(gè)概念。特權(quán)級(jí)一共有0-3這四個(gè)級(jí)別乏沸,0最高淫茵,可以管理CPU。
linux系統(tǒng)里面只有兩個(gè)級(jí)別屎蜓,0級(jí)和3級(jí)痘昌。操作系統(tǒng)的內(nèi)核當(dāng)然是最高級(jí)0級(jí),應(yīng)用程序是3級(jí)炬转。當(dāng)應(yīng)用程序需要訪問(wèn)系統(tǒng)資源時(shí)辆苔,CPU就進(jìn)入了內(nèi)核,從圖上看好像陷進(jìn)入一樣扼劈。

所謂的上下文驻啤,是指程序在運(yùn)行過(guò)程中的一些中間狀態(tài),比如會(huì)運(yùn)算出來(lái)一些值荐吵,這些值在后面的計(jì)算中也會(huì)用到骑冗。當(dāng)然這些值必須保存在內(nèi)存中。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末先煎,一起剝皮案震驚了整個(gè)濱河市贼涩,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌薯蝎,老刑警劉巖遥倦,帶你破解...
    沈念sama閱讀 217,657評(píng)論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異占锯,居然都是意外死亡袒哥,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,889評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門消略,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)堡称,“玉大人,你說(shuō)我怎么就攤上這事艺演∪唇簦” “怎么了?”我有些...
    開封第一講書人閱讀 164,057評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵胎撤,是天一觀的道長(zhǎng)晓殊。 經(jīng)常有香客問(wèn)我,道長(zhǎng)哩照,這世上最難降的妖魔是什么挺物? 我笑而不...
    開封第一講書人閱讀 58,509評(píng)論 1 293
  • 正文 為了忘掉前任懒浮,我火速辦了婚禮飘弧,結(jié)果婚禮上识藤,老公的妹妹穿的比我還像新娘。我一直安慰自己次伶,他們只是感情好痴昧,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,562評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著冠王,像睡著了一般赶撰。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上柱彻,一...
    開封第一講書人閱讀 51,443評(píng)論 1 302
  • 那天豪娜,我揣著相機(jī)與錄音,去河邊找鬼哟楷。 笑死瘤载,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的卖擅。 我是一名探鬼主播鸣奔,決...
    沈念sama閱讀 40,251評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼惩阶!你這毒婦竟也來(lái)了挎狸?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,129評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤断楷,失蹤者是張志新(化名)和其女友劉穎锨匆,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體脐嫂,經(jīng)...
    沈念sama閱讀 45,561評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡统刮,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,779評(píng)論 3 335
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了账千。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片侥蒙。...
    茶點(diǎn)故事閱讀 39,902評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖匀奏,靈堂內(nèi)的尸體忽然破棺而出鞭衩,到底是詐尸還是另有隱情,我是刑警寧澤娃善,帶...
    沈念sama閱讀 35,621評(píng)論 5 345
  • 正文 年R本政府宣布论衍,位于F島的核電站,受9級(jí)特大地震影響聚磺,放射性物質(zhì)發(fā)生泄漏坯台。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,220評(píng)論 3 328
  • 文/蒙蒙 一瘫寝、第九天 我趴在偏房一處隱蔽的房頂上張望蜒蕾。 院中可真熱鬧稠炬,春花似錦、人聲如沸咪啡。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,838評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)撤摸。三九已至毅桃,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間准夷,已是汗流浹背钥飞。 一陣腳步聲響...
    開封第一講書人閱讀 32,971評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留衫嵌,地道東北人代承。 一個(gè)月前我還...
    沈念sama閱讀 48,025評(píng)論 2 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像渐扮,于是被迫代替她去往敵國(guó)和親论悴。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,843評(píng)論 2 354