go 協(xié)程

進(jìn)程,線程

對于操作系統(tǒng)來說,一個任務(wù)就是一個進(jìn)程(Process).
有些進(jìn)程還不止同時干一件事泵琳,比如Word,它可以同時進(jìn)行打字誊役、拼寫檢查获列、打印等事情。在一個進(jìn)程內(nèi)部蛔垢,要同時干多件事击孩,就需要同時運(yùn)行多個“子任務(wù)”,我們把進(jìn)程內(nèi)的這些“子任務(wù)”稱為線程(Thread)鹏漆。
由于每個進(jìn)程至少要干一件事巩梢,所以,一個進(jìn)程至少有一個線程艺玲。

線程是最小的執(zhí)行單元括蝠,而進(jìn)程由至少一個線程組成,也是系統(tǒng)分配資源的最小單元,資,源分配給進(jìn)程,同一個進(jìn)程的所有線程共享該進(jìn)程所有資源饭聚。如何調(diào)度進(jìn)程和線程忌警,完全由操作系統(tǒng)決定,程序自己不能決定什么時候執(zhí)行秒梳,執(zhí)行多長時間法绵。

線程和進(jìn)程的關(guān)系
1箕速、一個進(jìn)程可以有多個線程,但至少有一個線程礼烈;而一個線程只能在一個進(jìn)程的地址空間內(nèi)活動弧满。
2婆跑、資源分配給進(jìn)程此熬,同一個進(jìn)程的所有線程共享該進(jìn)程所有資源。
3滑进、CPU分配給線程犀忱,即真正在處理器運(yùn)行的是線程。
4扶关、線程在執(zhí)行過程中需要協(xié)作同步阴汇,不同進(jìn)程的線程間要利用消息通信的辦法實(shí)現(xiàn)同步。

進(jìn)程與線程區(qū)別
1.同一個進(jìn)程中的線程共享同一內(nèi)存空間节槐,但是進(jìn)程之間是獨(dú)立的搀庶。
2.同一個進(jìn)程中的所有線程的數(shù)據(jù)是共享的(進(jìn)程通訊),進(jìn)程之間的數(shù)據(jù)是獨(dú)立的铜异。
3.對主線程的修改可能會影響其他線程的行為哥倔,但是父進(jìn)程的修改(除了刪除以外)不會影響其他子進(jìn)程。
4.線程是一個上下文的執(zhí)行指令揍庄,而進(jìn)程則是與運(yùn)算相關(guān)的一簇資源咆蒿。
5.同一個進(jìn)程的線程之間可以直接通信,但是進(jìn)程之間的交流需要借助中間代理來實(shí)現(xiàn)蚂子。
6.創(chuàng)建新的線程很容易沃测,但是創(chuàng)建新的進(jìn)程需要對父進(jìn)程做一次復(fù)制。
7.一個線程可以操作同一進(jìn)程的其他線程食茎,但是進(jìn)程只能操作其子進(jìn)程蒂破。
8.線程啟動速度快,進(jìn)程啟動速度慢(但是兩者運(yùn)行速度沒有可比性

協(xié)程

對于 協(xié)程(用戶級線程)别渔,這是對內(nèi)核透明的附迷,也就是系統(tǒng)并不知道有協(xié)程的存在,是完全由用戶自己的程序進(jìn)行調(diào)度的钠糊,因?yàn)槭怯捎脩舫绦蜃约嚎刂菩樱敲淳秃茈y像搶占式調(diào)度那樣做到強(qiáng)制的 CPU 控制權(quán)切換到其他進(jìn)程/線程,通常只能進(jìn)行 協(xié)作式調(diào)度抄伍,需要協(xié)程自己主動把控制權(quán)轉(zhuǎn)讓出去之后艘刚,其他協(xié)程才能被執(zhí)行到。

本質(zhì)上截珍,goroutine 就是協(xié)程攀甚。 不同的是箩朴,Golang 在 runtime、系統(tǒng)調(diào)用等多方面對 goroutine 調(diào)度進(jìn)行了封裝和處理秋度,當(dāng)遇到長時間執(zhí)行或者進(jìn)行系統(tǒng)調(diào)用時炸庞,會主動把當(dāng)前 goroutine 的CPU (P) 轉(zhuǎn)讓出去,讓其他 goroutine 能被調(diào)度并執(zhí)行荚斯,也就是 Golang 從語言層面支持了協(xié)程埠居。Golang 的一大特色就是從語言層面原生支持協(xié)程,在函數(shù)或者方法前面加 go關(guān)鍵字就可創(chuàng)建一個協(xié)程事期。

1. 內(nèi)存消耗方面

每個 goroutine (協(xié)程) 默認(rèn)占用內(nèi)存遠(yuǎn)比 Java 滥壕、C 的線程少。
    goroutine:2KB
    線程:8MB

2. 線程和 goroutine 切換調(diào)度開銷方面

線程/goroutine 切換開銷方面兽泣,goroutine 遠(yuǎn)比線程小
    線程:涉及模式切換(從用戶態(tài)切換到內(nèi)核態(tài))绎橘、16個寄存器、PC唠倦、SP...等寄存器的刷新等称鳞。
    goroutine:只有三個寄存器的值修改 - PC / SP / DX.

go 協(xié)程實(shí)現(xiàn)原理

他和線程的原理是一樣的,當(dāng) a線程 切換到 b線程 的時候稠鼻,需要將 a線程 的相關(guān)執(zhí)行進(jìn)度壓入棧冈止,然后將 b線程 的執(zhí)行進(jìn)度出棧,進(jìn)入 b線程 的執(zhí)行序列枷餐。協(xié)程只不過是在 應(yīng)用層 實(shí)現(xiàn)這一點(diǎn)靶瘸。但是,協(xié)程并不是由操作系統(tǒng)調(diào)度的毛肋,而且應(yīng)用程序也沒有能力和權(quán)限執(zhí)行 cpu 調(diào)度怨咪。怎么解決這個問題?

答案是润匙,協(xié)程是基于線程的诗眨。內(nèi)部實(shí)現(xiàn)上,維護(hù)了一組數(shù)據(jù)結(jié)構(gòu)和 n 個線程孕讳,真正的執(zhí)行還是線程匠楚,協(xié)程執(zhí)行的代碼被扔進(jìn)一個待執(zhí)行隊(duì)列中,由這 n 個線程從隊(duì)列中拉出來執(zhí)行厂财。這就解決了協(xié)程的執(zhí)行問題芋簿。那么協(xié)程是怎么切換的呢?答案是:golang 對各種 io函數(shù) 進(jìn)行了封裝璃饱,這些封裝的函數(shù)提供給應(yīng)用程序使用与斤,而其內(nèi)部調(diào)用了操作系統(tǒng)的異步 io函數(shù),當(dāng)這些異步函數(shù)返回 busy 或 bloking 時,golang 利用這個時機(jī)將現(xiàn)有的執(zhí)行序列壓棧撩穿,讓線程去拉另外一個協(xié)程的代碼來執(zhí)行磷支,基本原理就是這樣,利用并封裝了操作系統(tǒng)的異步函數(shù)食寡。包括 linux 的 epoll雾狈、select 和 windows 的 iocp、event 等抵皱。

由于golang是從編譯器和語言基礎(chǔ)庫多個層面對協(xié)程做了實(shí)現(xiàn)善榛,所以,golang的協(xié)程是目前各類有協(xié)程概念的語言中實(shí)現(xiàn)的最完整和成熟的叨叙。十萬個協(xié)程同時運(yùn)行也毫無壓力锭弊。關(guān)鍵我們不會這么寫代碼。但是總體而言擂错,程序員可以在編寫 golang 代碼的時候,可以更多的關(guān)注業(yè)務(wù)邏輯的實(shí)現(xiàn)樱蛤,更少的在這些關(guān)鍵的基礎(chǔ)構(gòu)件上耗費(fèi)太多精力钮呀。

參考:
Golang 之協(xié)程詳解
https://www.liaoxuefeng.com/wiki/1016959663602400/1017627212385376
http://www.reibang.com/p/a4f5c1c041ae
Golang源碼探索(二) 協(xié)程的實(shí)現(xiàn)原理

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市昨凡,隨后出現(xiàn)的幾起案子爽醋,更是在濱河造成了極大的恐慌,老刑警劉巖便脊,帶你破解...
    沈念sama閱讀 206,311評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件蚂四,死亡現(xiàn)場離奇詭異,居然都是意外死亡哪痰,警方通過查閱死者的電腦和手機(jī)遂赠,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,339評論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來晌杰,“玉大人跷睦,你說我怎么就攤上這事±哐荩” “怎么了抑诸?”我有些...
    開封第一講書人閱讀 152,671評論 0 342
  • 文/不壞的土叔 我叫張陵,是天一觀的道長爹殊。 經(jīng)常有香客問我蜕乡,道長,這世上最難降的妖魔是什么梗夸? 我笑而不...
    開封第一講書人閱讀 55,252評論 1 279
  • 正文 為了忘掉前任层玲,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘称簿。我一直安慰自己扣癣,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,253評論 5 371
  • 文/花漫 我一把揭開白布憨降。 她就那樣靜靜地躺著父虑,像睡著了一般。 火紅的嫁衣襯著肌膚如雪授药。 梳的紋絲不亂的頭發(fā)上士嚎,一...
    開封第一講書人閱讀 49,031評論 1 285
  • 那天,我揣著相機(jī)與錄音悔叽,去河邊找鬼莱衩。 笑死,一個胖子當(dāng)著我的面吹牛娇澎,可吹牛的內(nèi)容都是我干的笨蚁。 我是一名探鬼主播,決...
    沈念sama閱讀 38,340評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼趟庄,長吁一口氣:“原來是場噩夢啊……” “哼括细!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起戚啥,我...
    開封第一講書人閱讀 36,973評論 0 259
  • 序言:老撾萬榮一對情侶失蹤奋单,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后猫十,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體览濒,經(jīng)...
    沈念sama閱讀 43,466評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,937評論 2 323
  • 正文 我和宋清朗相戀三年拖云,在試婚紗的時候發(fā)現(xiàn)自己被綠了贷笛。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,039評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡江兢,死狀恐怖昨忆,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情杉允,我是刑警寧澤邑贴,帶...
    沈念sama閱讀 33,701評論 4 323
  • 正文 年R本政府宣布,位于F島的核電站叔磷,受9級特大地震影響拢驾,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜改基,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,254評論 3 307
  • 文/蒙蒙 一繁疤、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦稠腊、人聲如沸躁染。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,259評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽吞彤。三九已至,卻和暖如春叹放,著一層夾襖步出監(jiān)牢的瞬間饰恕,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工井仰, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留埋嵌,地道東北人。 一個月前我還...
    沈念sama閱讀 45,497評論 2 354
  • 正文 我出身青樓俱恶,卻偏偏與公主長得像雹嗦,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子速那,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,786評論 2 345

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

  • 進(jìn)程俐银、線程和協(xié)程 進(jìn)程的定義: 進(jìn)程,是計算機(jī)中已運(yùn)行程序的實(shí)體端仰。程序本身只是指令、數(shù)據(jù)及其組織形式的描述田藐,進(jìn)程才...
    星丶雲(yún)閱讀 1,406評論 2 14
  • 一荔烧、線程的實(shí)現(xiàn) 線程的實(shí)現(xiàn)方式主要有三種:內(nèi)核線程實(shí)現(xiàn)、用戶線程實(shí)現(xiàn)汽久、用戶線程加輕量級進(jìn)程混合實(shí)現(xiàn)鹤竭。因?yàn)樽约褐粚...
    非典型_程序員閱讀 5,600評論 0 2
  • Go 通過協(xié)程實(shí)現(xiàn)并發(fā)故爵,協(xié)程之間靠信道通信 1.1 并發(fā)刁俭、并行是什么? 并行其實(shí)很好理解散劫,就是同時執(zhí)行的意思稚机,在某...
    將軍紅閱讀 1,766評論 0 4
  • 在前面的教程里,我們探討了并發(fā)获搏,以及并發(fā)與并行的區(qū)別赖条。本教程則會介紹在 Go 語言里,如何使用 Go 協(xié)程(Gor...
    沒我找不到電子書閱讀 1,185評論 2 9
  • 1.做H5 App頁面時,有時候纬乍,按鈕可能會放到頁面的最底下碱茁,這個時候可能會用到絕對定位(position: ab...
    一一道長一一閱讀 835評論 0 1