一病袄、進(jìn)程
操作系統(tǒng)中最核心的概念是進(jìn)程搂赋,分布式系統(tǒng)中最重要的問題是進(jìn)程間通信。
進(jìn)程是“程序執(zhí)行的一個(gè)實(shí)例” 益缠,擔(dān)當(dāng)分配系統(tǒng)資源的實(shí)體脑奠。進(jìn)程創(chuàng)建必須分配一個(gè)完整的獨(dú)立地址空間。
進(jìn)程切換只發(fā)生在內(nèi)核態(tài)幅慌,兩步:1 切換頁全局目錄以安裝一個(gè)新的地址空間 2 切換內(nèi)核態(tài)堆棧和硬件上下文宋欺。 另一種說法類似:1 保存CPU環(huán)境(寄存器值、程序計(jì)數(shù)器胰伍、堆棧指針)2修改內(nèi)存管理單元MMU的寄存器 3 轉(zhuǎn)換后備緩沖器TLB中的地址轉(zhuǎn)換緩存內(nèi)容標(biāo)記為無效齿诞。
二、線程
書中的定義:線程是進(jìn)程的一個(gè)執(zhí)行流骂租,獨(dú)立執(zhí)行它自己的程序代碼祷杈。
維基百科:線程(英語:thread)是操作系統(tǒng)能夠進(jìn)行運(yùn)算調(diào)度的最小單位。
線程上下文一般只包含CPU上下文及其他的線程管理信息菩咨。線程創(chuàng)建的開銷主要取決于為線程堆棧的建立而分配內(nèi)存的開銷吠式,這些開銷并不大。線程上下文切換發(fā)生在兩個(gè)線程需要同步的時(shí)候抽米,比如進(jìn)入共享數(shù)據(jù)段。切換只CPU寄存器值需要存儲(chǔ)糙置,并隨后用將要切換到的線程的原先存儲(chǔ)的值重新加載到CPU寄存器中去云茸。
用戶級(jí)線程主要缺點(diǎn)在于對引起阻塞的系統(tǒng)調(diào)用的調(diào)用會(huì)立即阻塞該線程所屬的整個(gè)進(jìn)程。內(nèi)核實(shí)現(xiàn)線程則會(huì)導(dǎo)致線程上下文切換的開銷跟進(jìn)程一樣大谤饭,所以折衷的方法是輕量級(jí)進(jìn)程(Lightweight)标捺。在linux中,一個(gè)線程組基本上就是實(shí)現(xiàn)了多線程應(yīng)用的一組輕量級(jí)進(jìn)程揉抵。我理解為 進(jìn)程中存在用戶線程亡容、輕量級(jí)進(jìn)程、內(nèi)核線程冤今。
語言層面實(shí)現(xiàn)輕量級(jí)進(jìn)程的比較少闺兢,stackless python,erlang支持戏罢,java并不支持屋谭。
三脚囊、協(xié)程
協(xié)程的定義?顏開桐磁、許式偉均只說協(xié)程是輕量級(jí)的線程悔耘,一個(gè)進(jìn)程可輕松創(chuàng)建數(shù)十萬計(jì)的協(xié)程。仔細(xì)研究下我擂,個(gè)人感覺這些都是忽悠人的說法衬以。從維基百科上看,從Knuth老爺子的基本算法卷上看“子程序其實(shí)是協(xié)程的特例”校摩。子程序是什么看峻?子程序(英語:Subroutine, procedure, function, routine, method, subprogram),就是函數(shù)嘛秧耗!所以協(xié)程也沒什么了不起的备籽,就是種更一般意義的程序組件,那你內(nèi)存空間夠大分井,創(chuàng)建多少個(gè)函數(shù)還不是隨你么车猬?
協(xié)程可以通過yield來調(diào)用其它協(xié)程。通過yield方式轉(zhuǎn)移執(zhí)行權(quán)的協(xié)程之間不是調(diào)用者與被調(diào)用者的關(guān)系尺锚,而是彼此對稱珠闰、平等的。協(xié)程的起始處是第一個(gè)入口點(diǎn)瘫辩,在協(xié)程里伏嗜,返回點(diǎn)之后是接下來的入口點(diǎn)。子例程的生命期遵循后進(jìn)先出(最后一個(gè)被調(diào)用的子例程最先返回)伐厌;相反承绸,協(xié)程的生命期完全由他們的使用的需要決定。
線程和協(xié)程的區(qū)別:
一旦創(chuàng)建完線程挣轨,你就無法決定他什么時(shí)候獲得時(shí)間片军熏,什么時(shí)候讓出時(shí)間片了,你把它交給了內(nèi)核卷扮。而協(xié)程編寫者可以有一是可控的切換時(shí)機(jī)荡澎,二是很小的切換代價(jià)。從操作系統(tǒng)有沒有調(diào)度權(quán)上看晤锹,協(xié)程就是因?yàn)椴恍枰M(jìn)行內(nèi)核態(tài)的切換摩幔,所以會(huì)使用它,會(huì)有這么個(gè)東西鞭铆。賴永浩和dccmx 這個(gè)定義我覺得相對準(zhǔn)確 協(xié)程-用戶態(tài)的輕量級(jí)的線程或衡。(http://blog.dccmx.com/2011/04/coroutine-concept/)
為什么要用協(xié)程:
協(xié)程有助于實(shí)現(xiàn):
狀態(tài)機(jī):在一個(gè)子例程里實(shí)現(xiàn)狀態(tài)機(jī),這里狀態(tài)由該過程當(dāng)前的出口/入口點(diǎn)確定;這可以產(chǎn)生可讀性更高的代碼薇宠。
角色模型:并行的角色模型偷办,例如計(jì)算機(jī)游戲。每個(gè)角色有自己的過程(這又在邏輯上分離了代碼)澄港,但他們自愿地向順序執(zhí)行各角色過程的中央調(diào)度器交出控制(這是合作式多任務(wù)的一種形式)椒涯。
產(chǎn)生器:它有助于輸入/輸出和對數(shù)據(jù)結(jié)構(gòu)的通用遍歷。
顏開總結(jié)的支持協(xié)程的常見的語言和平臺(tái)回梧,可做參考废岂,但應(yīng)深入調(diào)研下才好。
四狱意、go中的Goroutine
go中的Goroutine湖苞, 普遍認(rèn)為是協(xié)程的go語言實(shí)現(xiàn)∠甓冢《Go語言編程》中說goroutine是輕量級(jí)線程(即協(xié)程coroutine, 原書90頁). 在第九章進(jìn)階話題中, 作者又一次提到, "從根本上來說, goroutine就是一種go語言版本的協(xié)程(coroutine)" (原書204頁). 但作者Rob Pike并不這么說财骨。
“一個(gè)Goroutine是一個(gè)與其他goroutines 并發(fā)運(yùn)行在同一地址空間的Go函數(shù)或方法。一個(gè)運(yùn)行的程序由一個(gè)或更多個(gè)goroutine組成藏姐。它與線程隆箩、協(xié)程、進(jìn)程等不同羔杨。它是一個(gè)goroutine捌臊。”
在棧實(shí)現(xiàn)上兜材,它的編譯器分支下的實(shí)現(xiàn)gccgo是線程pthread理澎,6g上是多路復(fù)用的threads(6g/8g/5g分別代表64位、32位及Arm架構(gòu)編譯器)
infoQ一篇文章介紹特性也說道: goroutine是Go語言運(yùn)行庫的功能曙寡,不是操作系統(tǒng)提供的功能糠爬,goroutine不是用線程實(shí)現(xiàn)的。具體可參見Go語言源碼里的pkg/runtime/proc.c
老趙認(rèn)為goroutine就是把類庫功能放進(jìn)了語言里举庶。
goroutine的并發(fā)問題:goroutine在共享內(nèi)存中運(yùn)行秩铆,通信網(wǎng)絡(luò)可能死鎖,多線程問題的調(diào)試糟糕透頂?shù)鹊鹊票洹R粋€(gè)比較好的建議規(guī)則:不要通過共享內(nèi)存通信,相反捅膘,通過通信共享內(nèi)存添祸。
并行 并發(fā)區(qū)別:
并行是指程序的運(yùn)行狀態(tài),要有兩個(gè)線程正在執(zhí)行才能算是Parallelism寻仗;并發(fā)指程序的邏輯結(jié)構(gòu)刃泌,Concurrency則只要有兩個(gè)以上線程還在執(zhí)行過程中即可。簡單地說,Parallelism要在多核或者多處理器情況下才能做到耙替,而Concurrency則不需要亚侠。(http://stackoverflow.com/questions/1050222/concurrency-vs-parallelism-what-is-the-difference)
參考資料:
《現(xiàn)代操作系統(tǒng)》《分布式系統(tǒng)原理與范型》《深入理解linux內(nèi)核》《go程序設(shè)計(jì)語言》
賴勇浩 協(xié)程三篇之僅一篇 http://blog.csdn.net/lanphaday/article/details/5397038
顏開 http://qing.blog.sina.com.cn/tj/88ca09aa33002ele.html
go程序設(shè)計(jì)語言中文 http://tonybai.com/2012/08/28/the-go-programming-language-tutorial-part3/ (中文翻譯定義中漏了個(gè) 并發(fā))
go程序設(shè)計(jì)語言英文http://go.googlecode.com/hg-history/release-branch.r60/doc/GoCourseDay3.pdf
go語言初體驗(yàn) http://blog.dccmx.com/2011/01/go-taste/
https://zh.wikipedia.org/wiki/Go
https://zh.wikipedia.org/wiki/進(jìn)程
https://zh.wikipedia.org/wiki/線程
http://stackoverflow.com/questions/1050222/concurrency-vs-parallelism-what-is-the-difference
http://www.infoq.com/cn/articles/knowledge-behind-goroutine
go語言編程書評(píng):http://book.douban.com/review/5726587/
源文轉(zhuǎn)自:http://studygolang.com/wr?u=http%3a%2f%2fblog.csdn.net%2fgaox587%2farticle%2fdetails%2f53005575