Golang中的協(xié)程(goroutine) | 您所在的位置:網(wǎng)站首頁 › 兄弟宮太陽化忌入夫妻宮 › Golang中的協(xié)程(goroutine) |
![]() 目錄 進(jìn)程 線程 并發(fā) 并行 協(xié)程(goroutine) ?使用sync.WaitGroup等待協(xié)程執(zhí)行完畢 多協(xié)程和多線程 進(jìn)程????????進(jìn)程就是程序在作系統(tǒng)中的一次執(zhí)行過程,是系統(tǒng)進(jìn)行資源分配和調(diào)度的基本單位,進(jìn)程是一個動態(tài)概念,是程序在執(zhí)行過程中分配和管理資源的基本單位,每一個進(jìn)程都有一個自己的地址空間。一個進(jìn)程至少有5種基本狀態(tài):初始狀態(tài),執(zhí)行狀態(tài),等待狀態(tài),就緒狀態(tài),終止?fàn)顟B(tài)。通俗的講,進(jìn)程就是一個正在執(zhí)行的程序。 線程????????線程是進(jìn)程的一個執(zhí)行實例,是程序執(zhí)行的最小單元,它是比進(jìn)程更小的能獨立運行的基本單位。一個進(jìn)程可以創(chuàng)建多個線程,同一個進(jìn)程中的多個線程可以并發(fā)執(zhí)行,一個程序要運行的話至少有一個進(jìn)程。 并發(fā)????????并發(fā)是指在同一時間段內(nèi)處理多個任務(wù),通過多個任務(wù)之間的切換,使得在表面上看來是同時進(jìn)行的。在 Go 語言中,可以使用 goroutine 和 channel 實現(xiàn)并發(fā)編程。 特點: 多個任務(wù)作用在一個CPU上面 同一時間點只能有一個任務(wù)執(zhí)行 同一時間段內(nèi)執(zhí)行多個任務(wù) 并行????????并行是指同時處理多個任務(wù),即多個任務(wù)同時在不同的處理器上進(jìn)行執(zhí)行。并行可以顯著提高程序的性能,特別是在多核 CPU 中,能夠利用多個 CPU 核心進(jìn)行計算。在 Go 語言中,可以使用 goroutine 和 runtime 包的 GOMAXPROCS 函數(shù)實現(xiàn)并行編程。 特點: 多個任務(wù)作用在多個CPU上面 同一時刻執(zhí)行多個任務(wù) ????????通俗的講,多線程程序在單核CPU上面運行就是并發(fā),多線程程序在多核CUP上運行就是并行,如果線程數(shù)大于CPU核數(shù),則多線程程序在多個CPU上面運行既有并行也有并發(fā)。 協(xié)程(goroutine)????????在 Go 語言中,協(xié)程(goroutine)是輕量級的線程,它是 Go 語言中實現(xiàn)并發(fā)編程的基礎(chǔ)。與傳統(tǒng)的線程相比,協(xié)程的創(chuàng)建和切換都非常輕量級,可以在單個線程內(nèi)創(chuàng)建成千上萬個協(xié)程,且切換開銷非常小,因此可以實現(xiàn)高效的并發(fā)編程。 ????????Go 語言中的協(xié)程是由 Go 運行時調(diào)度器(scheduler)進(jìn)行管理和調(diào)度的。當(dāng)程序啟動時,Go 運行時會默認(rèn)啟動一個主協(xié)程,主協(xié)程會創(chuàng)建其他的子協(xié)程,這些協(xié)程會被分配到不同的系統(tǒng)線程上進(jìn)行執(zhí)行。當(dāng)某個協(xié)程發(fā)生阻塞時,Go 運行時會將該協(xié)程掛起并讓出 CPU,轉(zhuǎn)而執(zhí)行其他協(xié)程,以充分利用系統(tǒng)資源。 在 Go 語言中,創(chuàng)建協(xié)程非常簡單,只需要在函數(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é)程計數(shù)器加-1 } func main() { //注意: ? ? //1.主線程執(zhí)行完畢后即使協(xié)程沒有執(zhí)行完畢程序也會退出 ? ? //2.協(xié)程可以在主線程沒有執(zhí)行完畢前提前退出,協(xié)程是否執(zhí)行完畢不會影響主線程的執(zhí)行 ? ? //為了保證我們的程序可以順利執(zhí)行,我們想讓協(xié)程執(zhí)行完畢后再執(zhí)行主進(jìn)程退出, ? ? //這個時候我們可以使用sync.WaitGroup等待協(xié)程執(zhí)行完畢 ? ? wg.Add(1) ?//協(xié)程計數(shù)器加1 ? ? go test1() //表示開啟一個協(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中每個goroutine(協(xié)程)默認(rèn)占用內(nèi)存比Java、C的線程少。OS線程(作系統(tǒng)線程)一般都有固定的棧內(nèi)存(通常為2MB左右),一個goroutine(協(xié)程)占用內(nèi)存非常少,只有2KB左右,多協(xié)程切換調(diào)度開銷方面遠(yuǎn)比線程要少。這也是為什么越來越多的大公司使用Golang的原因之一。 func test1() { ? ? for i := 0; i < 10; i++ { ? ? ? ? //每100毫秒輸出一次 ? ? ? ? fmt.Println("test1() 你好Golang-", i) ? ? ? ? time.Sleep(time.Millisecond * 100) ? ? } ? ? wg.Done() //協(xié)程計數(shù)器加-1 } func test2() { ? ? for i := 0; i < 10; i++ { ? ? ? ? //每100毫秒輸出一次 ? ? ? ? fmt.Println("test2() 你好Golang-", i) ? ? ? ? time.Sleep(time.Millisecond * 100) ? ? } ? ? wg.Done() //協(xié)程計數(shù)器加-1 } func main() { wg.Add(1) ?//協(xié)程計數(shù)器加1 ? ? go test1() //表示開啟一個協(xié)程 ? ? wg.Add(1) ?//協(xié)程計數(shù)器加1 ? ? go test2() //表示開啟一個協(xié)程 ? ? wg.Wait() ? ? fmt.Println("主程序退出。。。") } |
今日新聞 |
推薦新聞 |
專題文章 |
CopyRight 2018-2019 實驗室設(shè)備網(wǎng) 版權(quán)所有 |