淺析Golang中的協(xié)程(goroutine)
進(jìn)程
進(jìn)程就是程序在操作系統(tǒng)中的一次執(zhí)行過(guò)程,是系統(tǒng)進(jìn)行資源分配和調(diào)度的基本單位,進(jìn)程是一個(gè)動(dòng)態(tài)概念,是程序在執(zhí)行過(guò)程中分配和管理資源的基本單位,每一個(gè)進(jìn)程都有一個(gè)自己的地址空間。一個(gè)進(jìn)程至少有5種基本狀態(tài):初始狀態(tài),執(zhí)行狀態(tài),等待狀態(tài),就緒狀態(tài),終止?fàn)顟B(tài)。通俗的講,進(jìn)程就是一個(gè)正在執(zhí)行的程序。
線程
線程是進(jìn)程的一個(gè)執(zhí)行實(shí)例,是程序執(zhí)行的最小單元,它是比進(jìn)程更小的能獨(dú)立運(yùn)行的基本單位。一個(gè)進(jìn)程可以創(chuàng)建多個(gè)線程,同一個(gè)進(jìn)程中的多個(gè)線程可以并發(fā)執(zhí)行,一個(gè)程序要運(yùn)行的話至少有一個(gè)進(jìn)程。
并發(fā)
并發(fā)是指在同一時(shí)間段內(nèi)處理多個(gè)任務(wù),通過(guò)多個(gè)任務(wù)之間的切換,使得在表面上看來(lái)是同時(shí)進(jìn)行的。在 Go 語(yǔ)言中,可以使用 goroutine 和 channel 實(shí)現(xiàn)并發(fā)編程。
特點(diǎn):
多個(gè)任務(wù)作用在一個(gè)CPU上面
同一時(shí)間點(diǎn)只能有一個(gè)任務(wù)執(zhí)行
同一時(shí)間段內(nèi)執(zhí)行多個(gè)任務(wù)
并行
并行是指同時(shí)處理多個(gè)任務(wù),即多個(gè)任務(wù)同時(shí)在不同的處理器上進(jìn)行執(zhí)行。并行可以顯著提高程序的性能,特別是在多核 CPU 中,能夠利用多個(gè) CPU 核心進(jìn)行計(jì)算。在 Go 語(yǔ)言中,可以使用 goroutine 和 runtime 包的 GOMAXPROCS 函數(shù)實(shí)現(xiàn)并行編程。
特點(diǎn):
多個(gè)任務(wù)作用在多個(gè)CPU上面
同一時(shí)刻執(zhí)行多個(gè)任務(wù)
通俗的講,多線程程序在單核CPU上面運(yùn)行就是并發(fā),多線程程序在多核CUP上運(yùn)行就是并行,如果線程數(shù)大于CPU核數(shù),則多線程程序在多個(gè)CPU上面運(yùn)行既有并行也有并發(fā)。
協(xié)程(goroutine)
在 Go 語(yǔ)言中,協(xié)程(goroutine)是輕量級(jí)的線程,它是 Go 語(yǔ)言中實(shí)現(xiàn)并發(fā)編程的基礎(chǔ)。與傳統(tǒng)的線程相比,協(xié)程的創(chuàng)建和切換都非常輕量級(jí),可以在單個(gè)線程內(nèi)創(chuàng)建成千上萬(wàn)個(gè)協(xié)程,且切換開(kāi)銷非常小,因此可以實(shí)現(xiàn)高效的并發(fā)編程。
Go 語(yǔ)言中的協(xié)程是由 Go 運(yùn)行時(shí)調(diào)度器(scheduler)進(jìn)行管理和調(diào)度的。當(dāng)程序啟動(dòng)時(shí),Go 運(yùn)行時(shí)會(huì)默認(rèn)啟動(dòng)一個(gè)主協(xié)程,主協(xié)程會(huì)創(chuàng)建其他的子協(xié)程,這些協(xié)程會(huì)被分配到不同的系統(tǒng)線程上進(jìn)行執(zhí)行。當(dāng)某個(gè)協(xié)程發(fā)生阻塞時(shí),Go 運(yùn)行時(shí)會(huì)將該協(xié)程掛起并讓出 CPU,轉(zhuǎn)而執(zhí)行其他協(xié)程,以充分利用系統(tǒng)資源。
在 Go 語(yǔ)言中,創(chuàng)建協(xié)程非常簡(jiǎn)單,只需要在函數(shù)調(diào)用前加上 go 關(guān)鍵字即可。
例如:
func main() {
go func() {
fmt.Println("Hello, world!")
}()
}使用sync.WaitGroup等待協(xié)程執(zhí)行完畢
func test1() {
for i := 0; i < 10; i++ {
//每100毫秒輸出一次
fmt.Println("test1() 你好Golang-", i)
time.Sleep(time.Millisecond * 100)
}
wg.Done() //協(xié)程計(jì)數(shù)器加-1
}
func main() {
//注意:
//1.主線程執(zhí)行完畢后即使協(xié)程沒(méi)有執(zhí)行完畢程序也會(huì)退出
//2.協(xié)程可以在主線程沒(méi)有執(zhí)行完畢前提前退出,協(xié)程是否執(zhí)行完畢不會(huì)影響主線程的執(zhí)行
//為了保證我們的程序可以順利執(zhí)行,我們想讓協(xié)程執(zhí)行完畢后再執(zhí)行主進(jìn)程退出,
//這個(gè)時(shí)候我們可以使用sync.WaitGroup等待協(xié)程執(zhí)行完畢
wg.Add(1) //協(xié)程計(jì)數(shù)器加1
go test1() //表示開(kāi)啟一個(gè)協(xié)程
for i := 0; i < 10; i++ {
//每50毫秒輸出一次
fmt.Println("mian() 你好Golang-", i)
time.Sleep(time.Millisecond * 50)
}
wg.Wait() //等待協(xié)程執(zhí)行完畢
fmt.Println("主線程退出。。。")
}多協(xié)程和多線程
Golang中每個(gè)goroutine(協(xié)程)默認(rèn)占用內(nèi)存比Java、C的線程少。OS線程(操作系統(tǒng)線程)一般都有固定的棧內(nèi)存(通常為2MB左右),一個(gè)goroutine(協(xié)程)占用內(nèi)存非常少,只有2KB左右,多協(xié)程切換調(diào)度開(kāi)銷方面遠(yuǎn)比線程要少。這也是為什么越來(lái)越多的大公司使用Golang的原因之一。
func test1() {
for i := 0; i < 10; i++ {
//每100毫秒輸出一次
fmt.Println("test1() 你好Golang-", i)
time.Sleep(time.Millisecond * 100)
}
wg.Done() //協(xié)程計(jì)數(shù)器加-1
}
func test2() {
for i := 0; i < 10; i++ {
//每100毫秒輸出一次
fmt.Println("test2() 你好Golang-", i)
time.Sleep(time.Millisecond * 100)
}
wg.Done() //協(xié)程計(jì)數(shù)器加-1
}
func main() {
wg.Add(1) //協(xié)程計(jì)數(shù)器加1
go test1() //表示開(kāi)啟一個(gè)協(xié)程
wg.Add(1) //協(xié)程計(jì)數(shù)器加1
go test2() //表示開(kāi)啟一個(gè)協(xié)程
wg.Wait()
fmt.Println("主程序退出。。。")
}以上就是淺析Golang中的協(xié)程(goroutine)的詳細(xì)內(nèi)容,更多關(guān)于Golang 協(xié)程的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
- Go語(yǔ)言輕量級(jí)線程Goroutine用法實(shí)例
- go獲取協(xié)程(goroutine)號(hào)的實(shí)例
- go中控制goroutine數(shù)量的方法
- Golang 探索對(duì)Goroutine的控制方法(詳解)
- Go 防止 goroutine 泄露的方法
- golang goroutine順序輸出方式
- Go語(yǔ)言死鎖與goroutine泄露問(wèn)題的解決
- Go語(yǔ)言CSP并發(fā)模型goroutine及channel底層實(shí)現(xiàn)原理
- Go語(yǔ)言之使用pprof工具查找goroutine(協(xié)程)泄漏
- go語(yǔ)言面試之Goroutine詳解
相關(guān)文章
Golang設(shè)計(jì)模式之責(zé)任鏈模式講解和代碼示例
責(zé)任鏈?zhǔn)且环N行為設(shè)計(jì)模式, 允許你將請(qǐng)求沿著處理者鏈進(jìn)行發(fā)送, 直至其中一個(gè)處理者對(duì)其進(jìn)行處理,本文就詳細(xì)給大家介紹一下Golang 責(zé)任鏈模式,文中有詳細(xì)的代碼示例,需要的朋友可以參考下2023-06-06
go?sync.Once實(shí)現(xiàn)高效單例模式詳解
這篇文章主要為大家介紹了go?sync.Once實(shí)現(xiàn)高效單例模式詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-03-03
Go語(yǔ)言定時(shí)器Timer和Ticker的使用與區(qū)別
在Go語(yǔ)言中內(nèi)置的有兩個(gè)定時(shí)器,Timer和Ticker,本文主要介紹了Go語(yǔ)言定時(shí)器Timer和Ticker的使用與區(qū)別,具有一定的參考價(jià)值,感興趣的可以了解一下2024-07-07
GoFrame實(shí)現(xiàn)順序性校驗(yàn)示例詳解
這篇文章主要為大家介紹了GoFrame實(shí)現(xiàn)順序性校驗(yàn)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-06-06
Go語(yǔ)言fsnotify接口實(shí)現(xiàn)監(jiān)測(cè)文件修改
這篇文章主要為大家介紹了Go語(yǔ)言fsnotify接口實(shí)現(xiàn)監(jiān)測(cè)文件修改的示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-06-06
Go語(yǔ)言結(jié)合Wails構(gòu)建一個(gè)本地筆記工具
這篇文章主要為大家詳細(xì)介紹了Go語(yǔ)言如何結(jié)合Wails構(gòu)建一個(gè)本地筆記工具,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2026-04-04
golang內(nèi)存對(duì)齊的項(xiàng)目實(shí)踐
本文主要介紹了golang內(nèi)存對(duì)齊的項(xiàng)目實(shí)踐,內(nèi)存對(duì)齊不僅有助于提高內(nèi)存訪問(wèn)效率,還確保了與硬件接口的兼容性,是Go語(yǔ)言編程中不可忽視的重要優(yōu)化手段,下面就來(lái)介紹一下2025-02-02
Go語(yǔ)言中new()和 make()的區(qū)別詳解
這篇文章主要介紹了Go語(yǔ)言中new()和 make()的區(qū)別詳解,本文講解了new 的主要特性、make 的主要特性,并對(duì)它們的區(qū)別做了總結(jié),需要的朋友可以參考下2014-10-10

