網(wǎng)站首頁(yè) 編程語(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
相關(guān)推薦
- 2022-10-11 spingboot默認(rèn)日志系統(tǒng)LogBack、Log4j和slf4j使用詳解
- 2022-09-25 統(tǒng)一管理 Activity 便于隨時(shí)退出程序
- 2023-03-02 C++版本基于ros將文件夾中的圖像轉(zhuǎn)換為bag包_C 語(yǔ)言
- 2022-07-29 解決Vmware虛擬機(jī)安裝centos8報(bào)錯(cuò)“Section?%Packages?Does?Not?
- 2022-10-01 iOS簡(jiǎn)單實(shí)現(xiàn)輪播圖效果_IOS
- 2023-05-12 Python?pandas?的索引方式?data.loc[],data[][]示例詳解_python
- 2022-12-23 React使用Echarts/Ant-design-charts的案例代碼_React
- 2022-06-13 基于Python?matplotlib庫(kù)繪制箱線(xiàn)圖_python
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細(xì)win安裝深度學(xué)習(xí)環(huán)境2025年最新版(
- Linux 中運(yùn)行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲(chǔ)小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運(yùn)算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認(rèn)證信息的處理
- Spring Security之認(rèn)證過(guò)濾器
- Spring Security概述快速入門(mén)
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯(cuò)誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實(shí)現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡(jiǎn)單動(dòng)態(tài)字符串(SD
- arthas操作spring被代理目標(biāo)對(duì)象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊(duì)列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠(yuǎn)程分支