用大白話講進(jìn)程和線程驹愚、協(xié)程的區(qū)別

什么是進(jìn)程和線程

有一定基礎(chǔ)的小伙伴們肯定都知道進(jìn)程和線程远搪。

進(jìn)程是什么呢?

直白地講逢捺,進(jìn)程就是應(yīng)用程序的啟動(dòng)實(shí)例谁鳍。比如我們運(yùn)行一個(gè)游戲,打開一個(gè)軟件劫瞳,就是開啟了一個(gè)進(jìn)程倘潜。

進(jìn)程擁有代碼和打開的文件資源、數(shù)據(jù)資源志于、獨(dú)立的內(nèi)存空間涮因。

線程又是什么呢?

線程從屬于進(jìn)程伺绽,是程序的實(shí)際執(zhí)行者养泡。一個(gè)進(jìn)程至少包含一個(gè)主線程,也可以有更多的子線程奈应。

線程擁有自己的椑窖冢空間。


有人給出了很好的歸納:

對操作系統(tǒng)來說杖挣,線程是最小的執(zhí)行單元肩榕,進(jìn)程是最小的資源管理單元。

無論進(jìn)程還是線程惩妇,都是由操作系統(tǒng)所管理的点把。

Java中線程具有五種狀態(tài):

初始化

可運(yùn)行

運(yùn)行中

阻塞

銷毀

這五種狀態(tài)的轉(zhuǎn)化關(guān)系如下:


但是,線程不同狀態(tài)之間的轉(zhuǎn)化是誰來實(shí)現(xiàn)的呢屿附?是JVM嗎?

并不是哥童。JVM需要通過操作系統(tǒng)內(nèi)核中的TCB(Thread Control Block)模塊來改變線程的狀態(tài)挺份,這一過程需要耗費(fèi)一定的CPU資源。

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

線程之間是如何進(jìn)行協(xié)作的呢贮懈?

最經(jīng)典的例子就是生產(chǎn)者/消費(fèi)者模式

若干個(gè)生產(chǎn)者線程向隊(duì)列中寫入數(shù)據(jù)匀泊,若干個(gè)消費(fèi)者線程從隊(duì)列中消費(fèi)數(shù)據(jù)。

這段代碼做了下面幾件事:

1.定義了一個(gè)生產(chǎn)者類朵你,一個(gè)消費(fèi)者類各聘。

2.生產(chǎn)者類循環(huán)100次,向同步隊(duì)列當(dāng)中插入數(shù)據(jù)抡医。

3.消費(fèi)者循環(huán)監(jiān)聽同步隊(duì)列躲因,當(dāng)隊(duì)列有數(shù)據(jù)時(shí)拉取數(shù)據(jù)早敬。

4.如果隊(duì)列滿了(達(dá)到5個(gè)元素),生產(chǎn)者阻塞大脉。

5.如果隊(duì)列空了搞监,消費(fèi)者阻塞。

上面的代碼正確地實(shí)現(xiàn)了生產(chǎn)者/消費(fèi)者模式镰矿,但是卻并不是一個(gè)高性能的實(shí)現(xiàn)琐驴。為什么性能不高呢?原因如下:

1.涉及到同步鎖秤标。

2.涉及到線程阻塞狀態(tài)和可運(yùn)行狀態(tài)之間的切換绝淡。

3.涉及到線程上下文的切換。

以上涉及到的任何一點(diǎn)苍姜,都是非常耗費(fèi)性能的操作牢酵。

這個(gè)時(shí)候我們的主角 攜程,安老帧W旅薄!屈嗤! 不對不是這個(gè)攜程潘拨,是協(xié)程!H暮拧铁追! 就要登場了。

協(xié)程茫船,英文Coroutines琅束,是一種比線程更加輕量級的存在。正如一個(gè)進(jìn)程可以擁有多個(gè)線程一樣算谈,一個(gè)線程也可以擁有多個(gè)協(xié)程涩禀。協(xié)程的調(diào)度完全由用戶控制。協(xié)程擁有自己的寄存器上下文和棧然眼。協(xié)程調(diào)度切換時(shí)艾船,將寄存器上下文和棧保存到其他地方,在切回來的時(shí)候高每,恢復(fù)先前保存的寄存器上下文和棧屿岂,直接操作棧則基本沒有內(nèi)核切換的開銷,可以不加鎖的訪問全局變量鲸匿,所以上下文的切換非骋常快。協(xié)程與線程主要區(qū)別是它將不再被內(nèi)核調(diào)度带欢,而是交給了程序自己而線程是將自己交給內(nèi)核調(diào)度运授,所以也不難理解golang中調(diào)度器的存在烤惊。

最重要的是,協(xié)程不是被操作系統(tǒng)內(nèi)核所管理徒坡,而完全是由程序所控制(也就是在用戶態(tài)執(zhí)行)撕氧。

這樣帶來的好處就是性能得到了很大的提升,不會(huì)像線程切換那樣消耗資源喇完。



這段代碼十分簡單伦泥,即使沒用過python的小伙伴應(yīng)該也能基本看懂。

代碼中創(chuàng)建了一個(gè)叫做consumer的協(xié)程锦溪,并且在主線程中生產(chǎn)數(shù)據(jù)不脯,協(xié)程中消費(fèi)數(shù)據(jù)。

其中yield?是python當(dāng)中的語法刻诊。當(dāng)協(xié)程執(zhí)行到y(tǒng)ield關(guān)鍵字時(shí)防楷,會(huì)暫停在那一行,等到主線程調(diào)用send方法發(fā)送了數(shù)據(jù)则涯,協(xié)程才會(huì)接到數(shù)據(jù)繼續(xù)執(zhí)行复局。

但是,yield讓協(xié)程暫停粟判,和線程的阻塞是有本質(zhì)區(qū)別的亿昏。協(xié)程的暫停完全由程序控制,線程的阻塞狀態(tài)是由操作系統(tǒng)內(nèi)核來進(jìn)行切換档礁。

因此角钩,協(xié)程的開銷遠(yuǎn)遠(yuǎn)小于線程的開銷。

協(xié)程的應(yīng)用

有哪些編程語言應(yīng)用到了協(xié)程呢呻澜?我們舉幾個(gè)栗子:

Lua語言

Lua從5.0版本開始使用協(xié)程递礼,通過擴(kuò)展庫coroutine來實(shí)現(xiàn)。

Python語言

正如剛才所寫的代碼示例羹幸,python可以通過 yield/send 的方式實(shí)現(xiàn)協(xié)程脊髓。在python 3.5以后,?async/await 成為了更好的替代方案栅受。

Go語言

Go語言對協(xié)程的實(shí)現(xiàn)非常強(qiáng)大而簡潔供炼,可以輕松創(chuàng)建成百上千個(gè)協(xié)程并發(fā)執(zhí)行。

Java語言

如上文所說窘疮,Java語言并沒有對協(xié)程的原生支持,但是某些開源框架模擬出了協(xié)程的功能冀墨,有興趣的小伙伴可以看一看Kilim框架的源碼:

https://github.com/kilim/kilim

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末闸衫,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子诽嘉,更是在濱河造成了極大的恐慌蔚出,老刑警劉巖弟翘,帶你破解...
    沈念sama閱讀 222,183評論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異骄酗,居然都是意外死亡稀余,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,850評論 3 399
  • 文/潘曉璐 我一進(jìn)店門趋翻,熙熙樓的掌柜王于貴愁眉苦臉地迎上來睛琳,“玉大人,你說我怎么就攤上這事踏烙∈ζ” “怎么了?”我有些...
    開封第一講書人閱讀 168,766評論 0 361
  • 文/不壞的土叔 我叫張陵讨惩,是天一觀的道長辟癌。 經(jīng)常有香客問我,道長荐捻,這世上最難降的妖魔是什么黍少? 我笑而不...
    開封第一講書人閱讀 59,854評論 1 299
  • 正文 為了忘掉前任,我火速辦了婚禮处面,結(jié)果婚禮上厂置,老公的妹妹穿的比我還像新娘。我一直安慰自己鸳君,他們只是感情好农渊,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,871評論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著或颊,像睡著了一般砸紊。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上囱挑,一...
    開封第一講書人閱讀 52,457評論 1 311
  • 那天醉顽,我揣著相機(jī)與錄音,去河邊找鬼平挑。 笑死游添,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的通熄。 我是一名探鬼主播唆涝,決...
    沈念sama閱讀 40,999評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼唇辨!你這毒婦竟也來了廊酣?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,914評論 0 277
  • 序言:老撾萬榮一對情侶失蹤赏枚,失蹤者是張志新(化名)和其女友劉穎亡驰,沒想到半個(gè)月后晓猛,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,465評論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡凡辱,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,543評論 3 342
  • 正文 我和宋清朗相戀三年戒职,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片透乾。...
    茶點(diǎn)故事閱讀 40,675評論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡洪燥,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出续徽,到底是詐尸還是另有隱情蚓曼,我是刑警寧澤,帶...
    沈念sama閱讀 36,354評論 5 351
  • 正文 年R本政府宣布钦扭,位于F島的核電站纫版,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏客情。R本人自食惡果不足惜其弊,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,029評論 3 335
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望膀斋。 院中可真熱鬧梭伐,春花似錦、人聲如沸仰担。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,514評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽摔蓝。三九已至赂苗,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間贮尉,已是汗流浹背拌滋。 一陣腳步聲響...
    開封第一講書人閱讀 33,616評論 1 274
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留猜谚,地道東北人败砂。 一個(gè)月前我還...
    沈念sama閱讀 49,091評論 3 378
  • 正文 我出身青樓,卻偏偏與公主長得像魏铅,于是被迫代替她去往敵國和親昌犹。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,685評論 2 360

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