日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學(xué)無(wú)先后,達(dá)者為師

網(wǎng)站首頁(yè) 編程語(yǔ)言 正文

文字解說(shuō)Golang?Goroutine和線(xiàn)程的區(qū)別_Golang

作者:頭禿貓輕王 ? 更新時(shí)間: 2022-05-25 編程語(yǔ)言

Golang Goroutine和線(xiàn)程的區(qū)別 Golang,輕松學(xué)習(xí)

一、Golang Goroutine?

當(dāng)使用者分配足夠多的任務(wù),系統(tǒng)能自動(dòng)幫助使用者把任務(wù)分配到 CPU 上,讓這些任務(wù)盡量并發(fā)運(yùn)作。這種機(jī)制在 Go語(yǔ)言中被稱(chēng)為 goroutine。

goroutine 是 Go語(yǔ)言中的輕量級(jí)線(xiàn)程實(shí)現(xiàn),由 Go 運(yùn)行時(shí)(runtime)管理。Go 程序會(huì)智能地將 goroutine 中的任務(wù)合理地分配給每個(gè) CPU。

使用每一個(gè) go 關(guān)鍵字將會(huì)額外開(kāi)啟一個(gè)新的協(xié)程 goroutine

二、線(xiàn)程是什么?

線(xiàn)程(英語(yǔ):thread)是操作系統(tǒng)能夠進(jìn)行運(yùn)算調(diào)度的最小單位。它被包含在進(jìn)程之中,是進(jìn)程中的實(shí)際運(yùn)作單位。一條線(xiàn)程指的是進(jìn)程中一個(gè)單一順序的控制流,一個(gè)進(jìn)程中可以并發(fā)多個(gè)線(xiàn)程,每條線(xiàn)程并行執(zhí)行不同的任務(wù)。

三、調(diào)度的區(qū)別

1.線(xiàn)程調(diào)度

線(xiàn)程是系統(tǒng)調(diào)度的基本單位,線(xiàn)程作為調(diào)度與分配的基本單位,線(xiàn)程切換,僅需保存和設(shè)置少量寄存器的內(nèi)容,開(kāi)銷(xiāo)遠(yuǎn)小于進(jìn)程開(kāi)銷(xiāo)。但這種線(xiàn)程切換仍然需要一個(gè)完整的上下文切換:即保存一個(gè)線(xiàn)程的狀態(tài)到內(nèi)存,再恢復(fù)另外一個(gè)線(xiàn)程的狀態(tài),最后更新調(diào)度器的數(shù)據(jù)結(jié)構(gòu)。某種意義上,這種操作還是很慢的。

2.goroutine 調(diào)度

Go運(yùn)行的時(shí)候包涵一個(gè)自己的調(diào)度器,這個(gè)調(diào)度器使用一個(gè)稱(chēng)為一個(gè)M:N調(diào)度技術(shù),m個(gè)goroutine到n個(gè)os線(xiàn)程(可以用GOMAXPROCS來(lái)控制n的數(shù)量),Go的調(diào)度器不是由硬件時(shí)鐘來(lái)定期觸發(fā)的,而是由特定的go語(yǔ)言結(jié)構(gòu)來(lái)觸發(fā)的,他不需要切換到內(nèi)核語(yǔ)境,所以調(diào)度一個(gè)goroutine比調(diào)度一個(gè)線(xiàn)程的成本低很多。
Goroutine協(xié)程是一種協(xié)作任務(wù)控制機(jī)制,Goroutine可以理解為一種Go語(yǔ)言的協(xié)程。同時(shí)它可以運(yùn)行在一個(gè)或多個(gè)線(xiàn)程上。而Goroutine協(xié)程的切換一般由程序員在代碼中顯式控制。它避免了上下文切換的額外耗費(fèi),兼顧了多線(xiàn)程的優(yōu)點(diǎn),簡(jiǎn)化了高并發(fā)程序的復(fù)雜。

四、棧空間的區(qū)別

1.線(xiàn)程占用

每個(gè)OS的線(xiàn)程都有一個(gè)固定大小的棧內(nèi)存,通常是2MB,棧內(nèi)存用于保存在其他函數(shù)調(diào)用期間哪些正在執(zhí)行或者臨時(shí)暫停的函數(shù)的局部變量。這個(gè)固定的棧大小,如果對(duì)于goroutine來(lái)說(shuō),可能是一種巨大的浪費(fèi)。
以 64位環(huán)境的 JVM 為例,會(huì)默認(rèn)固定為每個(gè)線(xiàn)程分配 1MB 棧空間,如果大小分配不當(dāng),便會(huì)出現(xiàn)棧溢出的問(wèn)題。

2.goroutine 占用

- goroutine 所占用的內(nèi)存,均在棧中進(jìn)行管理 - goroutine 所占用的棧空間大小,由 runtime 按需進(jìn)行分配 goroutine在生命周期開(kāi)始只有一個(gè)很小的棧,典型情況是2KB, 在go程序中,一次創(chuàng)建十萬(wàn)左右的goroutine也不罕見(jiàn)(2KB*100,000=200MB)。而且goroutine的棧不是固定大小,它可以按需增大和縮小,最大限制可以到1GB。 goroutine 相較于線(xiàn)程更加輕量,關(guān)鍵點(diǎn)就在于棧空間的動(dòng)態(tài)分配,這樣便可以最大限度的利用內(nèi)存資源。

五、標(biāo)識(shí)的區(qū)別

1.線(xiàn)程標(biāo)識(shí)

在大部分支持多線(xiàn)程的操作系統(tǒng)和編程語(yǔ)言中,線(xiàn)程有一個(gè)獨(dú)特的標(biāo)識(shí),通常是一個(gè)整數(shù)或者指針,這個(gè)特性可以讓我們構(gòu)建一個(gè)線(xiàn)程的局部存儲(chǔ),本質(zhì)是一個(gè)全局的map,以線(xiàn)程的標(biāo)識(shí)作為鍵,這樣每個(gè)線(xiàn)程可以獨(dú)立使用這個(gè)map存儲(chǔ)和獲取值,不受其他線(xiàn)程干擾。

2.goroutine 標(biāo)識(shí)

goroutine中沒(méi)有可供程序員訪(fǎng)問(wèn)的標(biāo)識(shí),原因是一種純函數(shù)的理念,不希望濫用線(xiàn)程局部存儲(chǔ)導(dǎo)致一個(gè)不健康的超距作用,即函數(shù)的行為不僅取決于它的參數(shù),還取決于運(yùn)行它的線(xiàn)程標(biāo)識(shí)。

總結(jié)

Golang 通過(guò)復(fù)雜的協(xié)程操作來(lái)實(shí)現(xiàn)我們的并發(fā)需求,golang是用戶(hù)線(xiàn)程與系統(tǒng)線(xiàn)程的對(duì)應(yīng)關(guān)系是多對(duì)多,既能利用多核cpu資源,也能盡可能減少上下文切換成本,代價(jià)是go需要實(shí)現(xiàn)復(fù)雜的goroutine調(diào)度機(jī)制。
相比于N:1時(shí)所有用戶(hù)線(xiàn)程對(duì)應(yīng)1個(gè)系統(tǒng)線(xiàn)程,無(wú)法利用多核cpu;1:1時(shí)1個(gè)用戶(hù)線(xiàn)程對(duì)應(yīng)一個(gè)系統(tǒng)線(xiàn)程,上下文切換成本高。通過(guò)復(fù)雜的調(diào)度實(shí)現(xiàn)N:N時(shí),即能利用多核cpu資源,也能盡可能減少上下文切換成本,成為Go語(yǔ)言最為人知的特點(diǎn),天生支持高并發(fā)與高效。

原文鏈接:https://blog.csdn.net/moer0/article/details/123672726

欄目分類(lèi)
最近更新