第九章 基于共享變量的并發(fā)(二)Goroutine和線程

一凯旋、動態(tài)棧(Growable Stacks)

棧(stack):當(dāng)前正在被調(diào)用或被掛起(旨在調(diào)用其他函數(shù))的函數(shù)的內(nèi)部變量(local variables)被存放在棧中行剂。

操作系統(tǒng)(OS)線程 goroutine
類型 固定 動態(tài)
大小 通常2MB 2KB~1GB
特征 若線程所需內(nèi)存較少,會造成浪費(fèi)甩苛,比如需要大量功能簡單的線程時線程數(shù)量會受到限制文判;
若需要復(fù)雜或深層的遞歸調(diào)用物赶,則可能會不夠用橡庞。
一般從2KB大小的棧開始生命周期,根據(jù)實際需要動態(tài)伸縮印蔗。


二扒最、Goroutine調(diào)度(Scheduling)

OS內(nèi)核調(diào)度

OS線程由OS內(nèi)核調(diào)度,每幾毫秒华嘹,一個硬件計時器會中斷處理器吧趣,這會調(diào)用(invoke)一個叫scheduler的內(nèi)核函數(shù)進(jìn)行線程調(diào)度

scheduler函數(shù):1. 掛起當(dāng)前執(zhí)行的線程并保存其寄存器的內(nèi)容到內(nèi)存中;2. 選擇出下一個準(zhǔn)備執(zhí)行的線程耙厚,從內(nèi)存中恢復(fù)其寄存器的數(shù)據(jù)强挫,恢復(fù)執(zhí)行該線程的現(xiàn)場并開始執(zhí)行線程。

缺點(diǎn):線程的切換需要完整的上下文切換[1](包括 a. 保存一個用戶線程的狀態(tài)到內(nèi)存薛躬;b. 恢復(fù)另一個線程的到寄存器俯渤;c. 更新調(diào)度器的數(shù)據(jù)結(jié)構(gòu))。這個操作很慢型宝,因為相關(guān)數(shù)據(jù)在內(nèi)存中的位置往往較分散(poor locality)八匠,需要大量的內(nèi)存訪問。

Go的運(yùn)行期調(diào)度(runtime scheduling)

Go runtime包含自己的scheduler趴酣,其使用一種名為m:n調(diào)度(m:n scheduling)的技術(shù)梨树。

m:n調(diào)度(m:n scheduling):在n個OS線程上多工(multiplex)[2]調(diào)度m個goroutine

Go runtime的scheduler的工作內(nèi)容與OS的scheduler是類似的,不過只關(guān)注單獨(dú)(single)Go程序中的goroutines(即某一個Go程序中的goroutine只會與該程序中的其他goroutine交換)岖寞。

何時觸發(fā)調(diào)度:不由硬件計時器觸發(fā)抡四,而是由一些Go語言的結(jié)構(gòu)(constructs)隱式地觸發(fā)。例如當(dāng)一個goroutine調(diào)用了time.Sleep()仗谆,或者被channel或者mutex操作阻塞時指巡,調(diào)度器會使其進(jìn)入休眠并開始執(zhí)行另一個goroutine。直到Sleep()時間結(jié)束或者channel或mutex的阻塞解除后再喚醒第一個goroutine隶垮。

關(guān)于Go的線程調(diào)度是搶占式的還是協(xié)同式的:

go在1.4版本加入了搶占式邏輯厌处,之前的版本確實是非搶占式的,1.4以后版本的rutime sysmon會定期喚醒作系統(tǒng)狀態(tài)檢查岁疼,即使P處于阻塞的系統(tǒng)調(diào)也能被調(diào)用阔涉,不至于餓死,而且還檢查某個G是否過多的占用了的cpu時間捷绒,并在某個時刻剝奪其cpu運(yùn)行時間瑰排。[3]

優(yōu)點(diǎn):這種調(diào)度方式不需要進(jìn)入內(nèi)核的上下文,所以調(diào)度一個goroutine比調(diào)度一個線程代價要低得多暖侨。


三椭住、GOMAXPROCS

GOMAXPROCS變量

  • 決定會有多少個操作系統(tǒng)的線程同時執(zhí)行Go的代碼(m:n調(diào)度中的n)
  • 默認(rèn)值是CPU的核心數(shù)
  • 休眠中或者通信(communication)阻塞中的goroutine不需要對應(yīng)的系統(tǒng)線程
  • 在被I/O或其他系統(tǒng)調(diào)用阻塞時,或調(diào)用非Go語言函數(shù)時字逗,goroutine是需要一個對應(yīng)的操作系統(tǒng)線程的京郑,不過GOMAXPROCS不需要考慮這些情況
  • 修改方法:1. 修改環(huán)境變量GOMAXPROCS=n宅广;2. 運(yùn)行時調(diào)用runtime.GOMAXPROCS(n)函數(shù)

最佳線程數(shù)

最佳線程數(shù)與CPU核心數(shù)的關(guān)系并沒有定論,得具體情況具體分析些举,原則是活躍線程數(shù)為 CPU(核)數(shù)時最佳[4]跟狱。

介紹CPU時有的會提到n核m線程,這里的m可以理解為CPU中單一核心支持的最大并行(parallel)線程數(shù)户魏。

描述CPU時所說的多線程:Intel的超線程(Hyper-threading)[5]技術(shù)驶臊,旨在充分利用CPU核心中的資源。簡言之叼丑,假設(shè)有兩個線程A和B关翎,若A和B都(僅)需要核心中50%的某資源進(jìn)行運(yùn)算,則在應(yīng)用了超線程的核心中鸠信,A和B兩個線程可以同時進(jìn)行運(yùn)算(微觀上的并行)纵寝。不過使用超線程技術(shù)并不一定意味著性能的提升,在一些情況下星立,性能甚至可能下降[6]店雅。


四、Goroutine沒有識別符(Identity)

識別符帶來的問題

線程的身份信息會使得做一個抽象化的thread-local storage(線程本地存儲贞铣,多線程編程中不希望其它線程訪問的內(nèi)容)變得很容易闹啦,比如一個以線程的id為key的map。而這可能會導(dǎo)致一個函數(shù)的行為不是僅由其參數(shù)辕坝,而還由其運(yùn)行在的線程所決定窍奋。

Go鼓勵更簡單的編程風(fēng)格

影響函數(shù)行為的參數(shù)(parameters)都應(yīng)被顯式地指出。這樣不僅使程序變得更易讀酱畅,而且會讓我們向一些給定的函數(shù)分配子任務(wù)時不用擔(dān)心其身份信息會影響執(zhí)行結(jié)果琳袄。





1/16/18


  1. Context Switch ?

  2. 多工(多路復(fù)用) ?

  3. golang的goroutine調(diào)度到底是協(xié)作式的還是搶占式的? ?

  4. 多線程編程時纺酸,最佳線程數(shù)目與什么有關(guān)窖逗,核數(shù),還有其他的嗎餐蔬? - Name5566的回答 - 知乎 ?

  5. Hyper-threading ?

  6. 為什么 Intel 的超線程技術(shù)是一個核兩條線程碎紊,而不是更多? - 不祥之刃的回答 - 知乎 ?

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末樊诺,一起剝皮案震驚了整個濱河市仗考,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌词爬,老刑警劉巖秃嗜,帶你破解...
    沈念sama閱讀 217,406評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡锅锨,警方通過查閱死者的電腦和手機(jī)叽赊,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,732評論 3 393
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來必搞,“玉大人必指,你說我怎么就攤上這事」嘶” “怎么了取劫?”我有些...
    開封第一講書人閱讀 163,711評論 0 353
  • 文/不壞的土叔 我叫張陵匆笤,是天一觀的道長研侣。 經(jīng)常有香客問我,道長炮捧,這世上最難降的妖魔是什么庶诡? 我笑而不...
    開封第一講書人閱讀 58,380評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮咆课,結(jié)果婚禮上末誓,老公的妹妹穿的比我還像新娘。我一直安慰自己书蚪,他們只是感情好喇澡,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,432評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著殊校,像睡著了一般晴玖。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上为流,一...
    開封第一講書人閱讀 51,301評論 1 301
  • 那天呕屎,我揣著相機(jī)與錄音,去河邊找鬼敬察。 笑死秀睛,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的莲祸。 我是一名探鬼主播蹂安,決...
    沈念sama閱讀 40,145評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼锐帜!你這毒婦竟也來了藤抡?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,008評論 0 276
  • 序言:老撾萬榮一對情侶失蹤抹估,失蹤者是張志新(化名)和其女友劉穎缠黍,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體药蜻,經(jīng)...
    沈念sama閱讀 45,443評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡瓷式,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,649評論 3 334
  • 正文 我和宋清朗相戀三年替饿,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片贸典。...
    茶點(diǎn)故事閱讀 39,795評論 1 347
  • 序言:一個原本活蹦亂跳的男人離奇死亡视卢,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出廊驼,到底是詐尸還是另有隱情据过,我是刑警寧澤,帶...
    沈念sama閱讀 35,501評論 5 345
  • 正文 年R本政府宣布妒挎,位于F島的核電站绳锅,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏酝掩。R本人自食惡果不足惜鳞芙,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,119評論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望期虾。 院中可真熱鬧原朝,春花似錦、人聲如沸镶苞。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,731評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽茂蚓。三九已至壕鹉,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間煌贴,已是汗流浹背御板。 一陣腳步聲響...
    開封第一講書人閱讀 32,865評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留牛郑,地道東北人怠肋。 一個月前我還...
    沈念sama閱讀 47,899評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像淹朋,于是被迫代替她去往敵國和親笙各。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,724評論 2 354