golang筆記—— 進(jìn)程\線程\協(xié)程\Goroutine

一户誓、并發(fā)與并行

1. 并發(fā)

并發(fā)(Concurrent):1個(gè)CPU交錯(cuò)執(zhí)行2個(gè)任務(wù)袁串。單核系統(tǒng)中者冤,進(jìn)程(或線程)通過(guò)時(shí)間片或出讓控制權(quán)來(lái)實(shí)現(xiàn)任務(wù)切換无宿,以達(dá)到“同時(shí)”運(yùn)行多個(gè)程序的目的,實(shí)際上任何時(shí)刻都只有1個(gè)任務(wù)被執(zhí)行赂弓。宏觀上是“同時(shí)”執(zhí)行绑榴,微觀上是交錯(cuò)地順序執(zhí)行。

并發(fā)的特性

  • 系統(tǒng)資源被多個(gè)進(jìn)程(或線程)共享盈魁,造成程序結(jié)果不唯一
  • 進(jìn)程(或線程)結(jié)果的多變翔怎,導(dǎo)致進(jìn)程(或線程)運(yùn)行會(huì)出現(xiàn)不同的結(jié)果或偶發(fā)的異常
  • 多個(gè)進(jìn)程(或線程)間存在競(jìng)爭(zhēng)資源產(chǎn)生的互斥關(guān)系,也存在協(xié)作完成一個(gè)整體任務(wù)產(chǎn)生的同步關(guān)系杨耙。

能否很好地解決多個(gè)進(jìn)程(或線程)間的同步及互斥關(guān)系赤套,將決定程序能否正常運(yùn)行。

2. 并行

并行(Parallel):2個(gè)CPU分別同時(shí)各執(zhí)行了1個(gè)任務(wù)珊膜。多核系統(tǒng)中容握,理想情況下,可以讓多個(gè)進(jìn)程(或線程)做到真正意義上的同時(shí)執(zhí)行车柠,它們之間不需要排隊(duì)

通過(guò)下圖中Erlang 之父 Joe Armstrong對(duì)并發(fā)與并行的說(shuō)明剔氏,我們能清晰的區(qū)分并發(fā)與并行


二、進(jìn)程竹祷、線程谈跛、協(xié)程

1. 進(jìn)程

進(jìn)程(Process):是操作系統(tǒng)進(jìn)行資源分配和調(diào)度的一個(gè)獨(dú)立單位。是一個(gè)具有特定功能的程序運(yùn)行在一個(gè)數(shù)據(jù)集上的一次動(dòng)態(tài)過(guò)程塑陵。是應(yīng)用程序運(yùn)行的載體感憾。操作系統(tǒng)內(nèi)核通過(guò)進(jìn)程控制塊(PCB,process control block)來(lái)感知進(jìn)程令花。

進(jìn)程的組成

  • 程序:用于描述進(jìn)程要完成的功能阻桅,是控制進(jìn)程執(zhí)行的指令集凉倚。(進(jìn)程的執(zhí)行)
  • 數(shù)據(jù)集合:程序執(zhí)行時(shí)所需的數(shù)據(jù)和工作空間。(進(jìn)程的數(shù)據(jù)資源)
  • 進(jìn)程控制塊(PCB):但基本包括進(jìn)程標(biāo)識(shí)符嫂沉,當(dāng)前狀態(tài)占遥,現(xiàn)場(chǎng)保護(hù)區(qū),存儲(chǔ)指針输瓜,占用資源表以及進(jìn)程優(yōu)先級(jí)等信息。它是進(jìn)程存在的唯一標(biāo)志芬萍。(進(jìn)程的詳細(xì)信息)

進(jìn)程的切換


進(jìn)程切換尤揣,就是把進(jìn)程存放在處理器的寄存器中的中間數(shù)據(jù)存放到進(jìn)程的私有堆棧中,從而把處理器的寄存器騰出來(lái)讓其他進(jìn)程使用柬祠。這個(gè)中間數(shù)據(jù)北戏,就被稱作該進(jìn)程的上下文。進(jìn)程的切換實(shí)質(zhì)上就是被中止運(yùn)行進(jìn)程與待運(yùn)行進(jìn)程上下文的切換

進(jìn)程的狀態(tài)


就緒狀態(tài):進(jìn)程已獲得除處理器外的所需資源漫蛔,等待分配處理器資源嗜愈;只要分配了處理器進(jìn)程就可執(zhí)行。就緒進(jìn)程可以按多個(gè)優(yōu)先級(jí)來(lái)劃分隊(duì)列莽龟。
運(yùn)行狀態(tài):占有CPU蠕嫁,在CPU上執(zhí)行。
阻塞狀態(tài):由于進(jìn)程等待某種條件(如I/O操作或進(jìn)程同步)毯盈,在條件滿足之前無(wú)法繼續(xù)執(zhí)行剃毒。
創(chuàng)建狀態(tài):進(jìn)程正在被創(chuàng)建,系統(tǒng)為其初始化PCB搂赋,分配資源赘阀。
終止?fàn)顟B(tài):進(jìn)程正在從系統(tǒng)中撤銷,回收進(jìn)程的資源脑奠,撤銷其PCB基公。

進(jìn)程的通信方式

  • 管道
    管道可以看成是一種只存在內(nèi)存中,不存在于任何文件系統(tǒng)中的特殊文件宋欺,支持普通的read轰豆、write 等函數(shù)。分為以下兩種管道
    匿名管道(pipe)
    半雙工(即數(shù)據(jù)只能在一個(gè)方向上流動(dòng))齿诞,具有固定的讀端和寫端秒咨,只能用于具有親緣關(guān)系的進(jìn)程之間的通信。
    命名管道(FIFO)
    半雙工掌挚,有自己的名字和訪問(wèn)權(quán)限的限制雨席,就像一個(gè)文件一樣,它可以用于不相關(guān)進(jìn)程間的通信吠式,進(jìn)程通過(guò)使用命名管道的名字獲得管道陡厘。

    管道的特點(diǎn):寫滿時(shí)抽米,不能再寫;讀空時(shí)糙置,不能再讀
    使用場(chǎng)景:適合兩個(gè)進(jìn)程間發(fā)送非常短小的云茸、頻率很高的消息。

  • 消息隊(duì)列
    由消息組成的鏈表谤饭,存放在內(nèi)核中并由消息隊(duì)列標(biāo)識(shí)符標(biāo)識(shí)标捺。消息隊(duì)列是消息的鏈接表,包括Posix消息隊(duì)列system V消息隊(duì)列揉抵。有足夠權(quán)限的進(jìn)程可以向隊(duì)列中添加消息亡容,被賦予讀權(quán)限的進(jìn)程則可以讀走隊(duì)列中的消息。消息隊(duì)列克服了信號(hào)承載信息量少冤今,管道只能承載無(wú)格式字節(jié)流以及緩沖區(qū)大小受限等缺點(diǎn)闺兢。

  • 信號(hào)
    信號(hào)是一種非常短的消息,短到只有一個(gè)數(shù)字戏罢。一個(gè)進(jìn)程可以向另外一個(gè)進(jìn)程或者另外一組進(jìn)程發(fā)送信號(hào)消息屋谭,通知目標(biāo)進(jìn)程執(zhí)行特定的代碼

  • 信號(hào)量
    用于實(shí)現(xiàn)進(jìn)程間的互斥與同步,而不用于存儲(chǔ)進(jìn)程間通信數(shù)據(jù)龟糕,是一種保證共享資源有序訪問(wèn)的工具桐磁。

  • 共享內(nèi)存
    允許兩個(gè)或多個(gè)進(jìn)程共享一個(gè)給定的存儲(chǔ)區(qū),這一段存儲(chǔ)區(qū)可以被兩個(gè)或兩個(gè)以上的進(jìn)程映射至自身的地址空間中讲岁,一個(gè)進(jìn)程寫入共享內(nèi)存的信息所意,可以被其他使用這個(gè)共享內(nèi)存的進(jìn)程。
    共享內(nèi)存將保持到通信完畢為止催首,不會(huì)頻繁解除內(nèi)存映射或重建內(nèi)存共享區(qū)域扶踊,因此共享內(nèi)存的通信方式效率非常高。
    使用場(chǎng)景:適合多進(jìn)程間共享的郎任、非常龐大的秧耗、讀寫操作頻率很高的數(shù)據(jù)通信。

  • 網(wǎng)絡(luò)Socket
    網(wǎng)絡(luò)環(huán)境中進(jìn)程間通信的API舶治。與其他通信機(jī)制不同的是分井,它可用于不同機(jī)器間的進(jìn)程通信。
    使用場(chǎng)景:適用于分布式開發(fā)

2. 線程

線程(thread):是操作系統(tǒng)能夠進(jìn)行運(yùn)算調(diào)度的最小單位霉猛,它被包含在進(jìn)程之中尺锚,是進(jìn)程中的實(shí)際運(yùn)作單位。

線程的分類

線程的實(shí)現(xiàn)可以分為兩類:

1)用戶級(jí)線程(User-Level Thread)

由進(jìn)程負(fù)責(zé)調(diào)度管理惜浅,不依賴于操作系統(tǒng)內(nèi)核
優(yōu)點(diǎn):

  • 線程位于用戶空間(即不需要模式切換)瘫辩。
  • 完全控制線程調(diào)度器(例如:網(wǎng)站服務(wù)器)。
  • 獨(dú)立于操作系統(tǒng)(線程可以在不支持它們的操作系統(tǒng)上運(yùn)行)。
  • 運(yùn)行時(shí)系統(tǒng)(run time system)可以切換用戶空間中的本地阻塞線程(例如:等待另一個(gè)線程完成)伐厌。

缺點(diǎn):

  • 系統(tǒng)調(diào)度中承绸,對(duì)一個(gè)線程的阻塞將會(huì)導(dǎo)致整個(gè)進(jìn)程阻塞(例如:當(dāng)一個(gè)線程因 I/O 而處于等待狀態(tài)時(shí),整個(gè)進(jìn)程就會(huì)被調(diào)度程序切換為等待狀態(tài)挣轨,其他線程得不到運(yùn)行的機(jī)會(huì))军熏。
  • 網(wǎng)站服務(wù)器中,一個(gè)頁(yè)面的錯(cuò)誤將導(dǎo)致整個(gè)進(jìn)程阻塞卷扮。
  • 非真正意義的線程并行(一個(gè)進(jìn)程安排在單個(gè)CPU上)荡澎。
  • 不存在時(shí)鐘中斷(例如,如果用戶線程是非搶占式的晤锹,將無(wú)法被“進(jìn)程調(diào)度”以round-robin的調(diào)度算法調(diào)用摩幔,因?yàn)閞ound-robin調(diào)度算法中限制了cpu時(shí)間片)。
2)內(nèi)核級(jí)線程(Kernel-Level Thread)

由操作系統(tǒng)支持和管理
優(yōu)點(diǎn):

  • 實(shí)現(xiàn)了真正意義上的線程并行抖甘。
  • 不需要運(yùn)行時(shí)系統(tǒng)的參與。

缺點(diǎn):
頻繁的模式切換導(dǎo)致內(nèi)核開支葫慎。

線程的同步

當(dāng)多個(gè)線程同時(shí)讀寫同一份共享資源的時(shí)候衔彻,可能會(huì)引起沖突,這時(shí)候偷办,我們需要引入線程“同步”機(jī)制艰额。線程同步是為了防止多個(gè)線程同時(shí)訪問(wèn)同一個(gè)數(shù)據(jù)對(duì)象時(shí),對(duì)數(shù)據(jù)造成破壞椒涯。線程的同步是保證多線程安全訪問(wèn)資源的一種手段柄沮。

主要通過(guò)臨界區(qū)(Critical Section)、互斥對(duì)象(Mutex)的機(jī)制來(lái)實(shí)現(xiàn)互斥控制废岂,在Java中分別對(duì)應(yīng)synchornized及對(duì)象鎖祖搓;通過(guò)信號(hào)量(Semaphore)、事件對(duì)象(Event)以通知的方式進(jìn)行同步控制湖苞,在Java中分別對(duì)應(yīng)wait()拯欧、notify()等方法。

也可以通過(guò)寫時(shí)復(fù)制(Copy On Write)的無(wú)鎖方式來(lái)實(shí)現(xiàn)線程的同步财骨,即在每個(gè)線程中拷貝一份共享資源的副本镐作。

線程的出現(xiàn),是為了分離進(jìn)程的兩個(gè)功能:資源分配和系統(tǒng)調(diào)度隆箩。讓更細(xì)粒度该贾、更輕量的線程來(lái)承擔(dān)調(diào)度,減輕調(diào)度帶來(lái)的開銷捌臊。但線程還是不夠輕量杨蛋,因?yàn)檎{(diào)度是在內(nèi)核空間進(jìn)行的,每次線程切換都需要陷入內(nèi)核,這個(gè)開銷還是不可忽視的六荒。協(xié)程則是把調(diào)度邏輯在用戶空間里實(shí)現(xiàn)护姆,通過(guò)自己(編譯器運(yùn)行時(shí)系統(tǒng)/程序員)模擬控制權(quán)的交接,來(lái)達(dá)到更加細(xì)粒度的控制掏击。
在操作系統(tǒng)的OS Thread和編程語(yǔ)言的User Thread之間卵皂,實(shí)際上存在3種線程對(duì)應(yīng)模型,也就是:1:1砚亭,1:N灯变,M:N。

  • 1:1:一個(gè)用戶線程就只在一個(gè)內(nèi)核線程上跑捅膘,這時(shí)可以利用多核添祸,但是上下文切換很慢,切換效率很低寻仗。
  • N:1:多個(gè)(N)用戶線程始終在一個(gè)內(nèi)核線程上跑刃泌,context上下文切換很快,但是無(wú)法真正的利用多核署尤。
  • M:N:多個(gè)用戶線程在多個(gè)內(nèi)核線程上跑耙替,這個(gè)可以集齊上面兩者的優(yōu)勢(shì),既能快速切換上下文,也能利用多核的優(yōu)勢(shì)

3. 協(xié)程

協(xié)程(Coroutine):是一種用戶級(jí)的輕量線程曹体,擁有自己獨(dú)立的棧和共享的堆俗扇,共享堆,不共享?xiàng);稹f(xié)程由程序員在協(xié)程的代碼里顯示調(diào)度铜幽。進(jìn)程、線程是操作系統(tǒng)級(jí)別的概念串稀,而協(xié)程是編譯器級(jí)別的除抛,協(xié)程間切換只需要保存任務(wù)的上下文,沒(méi)有內(nèi)核的開銷母截。
協(xié)程的優(yōu)勢(shì)

  • 內(nèi)存占用少
  • 上下文切換代價(jià)小

4. goroutine

Goroutine基本概念

  • goroutine是Go語(yǔ)言運(yùn)行庫(kù)的功能镶殷,不是操作系統(tǒng)提供的功能,goroutine不是用線程實(shí)現(xiàn)的微酬,而是go語(yǔ)言實(shí)現(xiàn)的用戶態(tài)線程绘趋。
  • goroutine就是一段代碼,一個(gè)函數(shù)入口颗管,以及在堆上為其分配的一個(gè)堆棧陷遮。所以它非常廉價(jià),我們可以很輕松的創(chuàng)建上萬(wàn)個(gè)goroutine垦江,但它們并不是被操作系統(tǒng)所調(diào)度執(zhí)行帽馋。
  • goroutine來(lái)自協(xié)程的概念,讓一組可復(fù)用的函數(shù)運(yùn)行在一組線程之上,即使有g(shù)oroutine阻塞绽族,該線程的其他goroutine也可以被runtime調(diào)度姨涡,轉(zhuǎn)移到其他可運(yùn)行的線程上。這更像是多線程和協(xié)程的綜合體吧慢,能最大限度提升執(zhí)行效率涛漂,發(fā)揮多核處理能力。

Goroutine特點(diǎn)

  • 占用內(nèi)存更屑焓(幾kb)
  • 調(diào)度更靈活(runtime調(diào)度)

參考文檔:
https://zhuanlan.zhihu.com/p/137339439
https://zhuanlan.zhihu.com/p/260830550
https://zhuanlan.zhihu.com/p/51194025
https://www.cnblogs.com/LUO77/p/5816326.html
https://blog.csdn.net/cafucwxy/article/details/78453430
https://blog.csdn.net/zhaohong_bo/article/details/89552188
https://www.coder55.com/article/11579
http://www.sizeofvoid.net/goroutine-under-the-hood/
https://zhuanlan.zhihu.com/p/68299348

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末匈仗,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子逢慌,更是在濱河造成了極大的恐慌悠轩,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,542評(píng)論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件攻泼,死亡現(xiàn)場(chǎng)離奇詭異火架,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)忙菠,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,822評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門何鸡,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人只搁,你說(shuō)我怎么就攤上這事音比〖蠹猓” “怎么了氢惋?”我有些...
    開封第一講書人閱讀 163,912評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)稽犁。 經(jīng)常有香客問(wèn)我焰望,道長(zhǎng),這世上最難降的妖魔是什么已亥? 我笑而不...
    開封第一講書人閱讀 58,449評(píng)論 1 293
  • 正文 為了忘掉前任熊赖,我火速辦了婚禮,結(jié)果婚禮上虑椎,老公的妹妹穿的比我還像新娘震鹉。我一直安慰自己,他們只是感情好捆姜,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,500評(píng)論 6 392
  • 文/花漫 我一把揭開白布传趾。 她就那樣靜靜地躺著,像睡著了一般泥技。 火紅的嫁衣襯著肌膚如雪浆兰。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,370評(píng)論 1 302
  • 那天尘奏,我揣著相機(jī)與錄音蝗拿,去河邊找鬼。 笑死蛹找,一個(gè)胖子當(dāng)著我的面吹牛蜕便,可吹牛的內(nèi)容都是我干的劫恒。 我是一名探鬼主播,決...
    沈念sama閱讀 40,193評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼玩裙,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼兼贸!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起吃溅,我...
    開封第一講書人閱讀 39,074評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤溶诞,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后决侈,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體螺垢,經(jīng)...
    沈念sama閱讀 45,505評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,722評(píng)論 3 335
  • 正文 我和宋清朗相戀三年赖歌,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了枉圃。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,841評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡庐冯,死狀恐怖孽亲,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情展父,我是刑警寧澤返劲,帶...
    沈念sama閱讀 35,569評(píng)論 5 345
  • 正文 年R本政府宣布,位于F島的核電站栖茉,受9級(jí)特大地震影響篮绿,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜吕漂,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,168評(píng)論 3 328
  • 文/蒙蒙 一亲配、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧惶凝,春花似錦吼虎、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,783評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至坡贺,卻和暖如春官辈,著一層夾襖步出監(jiān)牢的瞬間箱舞,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,918評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工拳亿, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留晴股,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,962評(píng)論 2 370
  • 正文 我出身青樓肺魁,卻偏偏與公主長(zhǎng)得像电湘,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子鹅经,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,781評(píng)論 2 354

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

  • 人是一種高并發(fā)的物種寂呛,細(xì)品。 初識(shí) 對(duì) Go 語(yǔ)言的第一印象就是其原生地支持并發(fā)編程瘾晃,而且使用的是協(xié)程贷痪,比線程更加...
    K8sCat閱讀 36,912評(píng)論 0 1
  • 并發(fā)基礎(chǔ) 在說(shuō)Golang的并發(fā)編程之前,先認(rèn)識(shí)一下目前并發(fā)的幾種實(shí)現(xiàn)方式: 1.多進(jìn)程蹦误。操作系統(tǒng)實(shí)現(xiàn)的并發(fā)模型劫拢,...
    睡著別叫醒我閱讀 2,226評(píng)論 0 1
  • 看了一天的相關(guān)概念,很多涉及到操作系統(tǒng)與底層硬件層面,腦子有點(diǎn)暈,對(duì)自己所理解的東西清理一下并記錄下來(lái),有些不對(duì)的...
    尋找無(wú)雙丶閱讀 3,592評(píng)論 0 1
  • 1. 并行和并發(fā) 并行:在同一時(shí)刻,有多條指令在多個(gè)CPU處理器上同時(shí)執(zhí)行 2個(gè)隊(duì)伍强胰,2個(gè)窗口舱沧,要求硬件支持 并發(fā)...
    陳光環(huán)_18閱讀 261評(píng)論 0 0
  • 本文是在上一篇文章的基礎(chǔ)上Golang之并發(fā)編程一的基礎(chǔ)上的續(xù)篇,如果有興趣的話偶洋,大家可以先看看上一篇的內(nèi)容熟吏,也希...
    睡著別叫醒我閱讀 346評(píng)論 0 0